给你两个答案:
使用 CommonJS (CJS)
使用 CommonJS(您在该示例中使用的模块系统),最好的办法是导出 promise。这样,使用你的模块的代码就有了一种标准的方式来处理这个值可能还不可用的事实——消费承诺:
require("./your-moudule")
.then(AS => {
// ...use `AS` here...
})
.catch(error => {
// ...handle the fact we didn't get it here...
});
但是,如果您想改为导出值,则可以,但这通常不是您的最佳方法。你可以通过导出一个对象然后更新它的AS 属性来做到这一点:
function go() {
return new Promise((resolve, reject) => {
setTimeout(() => resolve("Success!"), 500);
});
}
module.exports = {AS: undefined};
go().then((x) => {
module.exports.AS = x;
});
使用您的模块的模块将不得不处理这样一个事实,即它们会在一段时间内得到undefined。这是使用上述模块的代码:
const mod = require("./promise");
const timer = setInterval(() => {
const AS = mod.AS;
console.log("AS = " + AS);
if (AS) {
clearInterval(timer);
}
}, 100);
如果你运行它,你会看到AS = undefined ~5 次,然后是AS = Success!。
使用 JavaScript 模块 (ESM)
如果您可以改用 JavaScript 模块(Node.js 在 v12 中支持它们在标志后面,而在 v13+ 中没有标志,请将 "type": "module" 放在您的 package.json 中),您还有第三种选择:@987654321 @。使用顶级await(在我写这篇文章时积极地添加到 JavaScript 引擎中),你可以让你的模块执行等待一个承诺解决。所以你会这样做:
function go() {
return new Promise((resolve, reject) => {
setTimeout(() => resolve("Success!"), 500);
});
}
const AS = await go();
export default AS; // Or `export { AS };`, but your CJS code was effectively doing `export default`
您可以根据需要合并这些行。对于默认导出
export default await go();
对于命名导出:
export const AS = await go();
使用您的模块的模块不必知道AS 值来自异步源这一事实;在您的模块评估完成之前(在承诺确定之后),它们不会被评估。他们只是像往常一样导入:
import AS from "./promise.js"; // If it's the default export
console.log("AS = " + AS);
顶级await 位于--harmony-top-level-await 标志后面的Node v13+ 中,很快就会进入浏览器。