Node.js es6模块导出异步变量

Node.js es6模块导出异步变量,node.js,ecmascript-6,Node.js,Ecmascript 6,我使用supertest实现了在用户登录后运行的测试: // ../prepare.login "use strict"; import {default as request} from "supertest"; import {default as app} from "../../server.js"; const postUrl = "/api/v1/login"; const postData = { "username": "user", "password":

我使用
supertest
实现了在用户登录后运行的测试:

// ../prepare.login
"use strict";

import {default as request} from "supertest";
import {default as app} from "../../server.js";

const postUrl = "/api/v1/login";
const postData = {
    "username": "user",
    "password": "pass"
    };

module.exports = {
    prepare: function(done) {
        request(app.listen())
            .post(postUrl)
            .send(postData)
            .end((err, res) => {
                if (err) {
                    throw err;
                }
                module.exports.token = res.body.token;
                done();
            });
    }
}
到目前为止,我一直在使用es5,并使用
module.exports.token
作为一种难看的黑客手段将令牌发送到实际测试:

// users.js
...
var login = require("../prepare.login");

describe("authenticated /api/v1/users", function() {
beforeEach(function(done) {
        login.prepare(done);
    });
});

...

it("On GET /api/v1/users I want to get all the users in an array", function(done) {
        request(app.listen())
            .get("/api/v1/users")
            .set("X-Access-Token", login.token)
            .expect(200)
            ...
我切换到es6,它不允许
import
export
语句出现在模块顶层以外的任何地方。因此,我不确定该如何实现。我应该异步等待结果吗?有可能吗?还有别的办法吗

es6不允许在模块顶层以外的任何地方导入和导出状态

是的,但这只是变量声明需要的地方。你仍然可以分配给他们你想要的任何地方

import {default as request} from "supertest";
import {default as app} from "../../server.js";

const postUrl = "/api/v1/login";
const postData = {
    "username": "user",
    "password": "pass"
};

export let token = null;
export function prepare(done) {
    request(app.listen())
        .post(postUrl)
        .send(postData)
        .end((err, res) => {
            if (err) return done(err);
            token = res.body.token;
            done();
        });
}

还有别的办法吗

对。您应该将
标记
传递给回调,而不是变异全局变量(自古以来就被轻视):

…
.end((err, res) => {
    if (err) done(err);
    else done(null, res.body.token);
});
这样您就可以在需要的地方提取它:

let token = null;
describe("authenticated /api/v1/users", function() {
    beforeEach(function(done) {
        login.prepare(function(err, t) {
            if (err) return done(err);
            token = t;
            done();
        });
    });
});
还有更好的办法吗

与第二种方法一样,不要使用导出的变量;但与其调用繁琐的回调,不如返回令牌的承诺

let token = null;
describe("authenticated /api/v1/users", function() {
    beforeEach(function(done) {
        login.prepare(function(err, t) {
            if (err) return done(err);
            token = t;
            done();
        });
    });
});