Tig*_*yan 2 javascript asynchronous export node.js
假设我想在单个 JS 模块中导出一些通过调用某个异步函数获得的值。使导出等待结果/Promise 解决的机制是什么?
作为示例代码片段,我将其放在这里
function go() {
return new Promise((resolve, reject) => {
setTimeout(() => resolve("Success!"), 3000);
});
}
let AS;
go().then((x) => {
AS = x;
});
module.exports = AS;
Run Code Online (Sandbox Code Playgroud)
该函数可以发出任何 API 请求。我不想导出整个函数并在其他模块中调用它。
给你两个答案:
\n对于 CommonJS(您在该示例中使用的模块系统),最好的选择是导出承诺。这样,使用模块的代码就有一种标准方法来处理该值可能尚不可用的事实\xc2\xa0\xe2\x80\x94 消费承诺:
\nrequire("./your-moudule")\n.then(AS => {\n // ...use `AS` here...\n})\n.catch(error => {\n // ...handle the fact we didn\'t get it here...\n});\nRun Code Online (Sandbox Code Playgroud)\n但如果您想导出该值,也可以,但这通常不是您的最佳方法。您可以通过导出对象然后更新其AS属性来做到这一点:
function go() {\n return new Promise((resolve, reject) => {\n setTimeout(() => resolve("Success!"), 500);\n });\n}\n\nmodule.exports = {AS: undefined};\ngo().then((x) => {\n module.exports.AS = x;\n});\nRun Code Online (Sandbox Code Playgroud)\n使用您的模块的模块必须处理这样一个事实:在一段时间内,它们将获得undefined. 这是使用上面模块的代码:
const mod = require("./promise");\nconst timer = setInterval(() => {\n const AS = mod.AS;\n console.log("AS = " + AS);\n if (AS) {\n clearInterval(timer);\n }\n}, 100);\nRun Code Online (Sandbox Code Playgroud)\n如果你运行它,你会看到AS = undefined~5 次,然后AS = Success!.
如果您可以改用 JavaScript 模块(Node.js 在 v12 中支持它们后面的标志,而在 v13+ 中没有标志,请放入"type": "module"您的package.json),您还有第三个选择:顶级await。通过顶层await(在我编写本文时主动添加到 JavaScript 引擎中),您可以让模块执行等待 Promise 解决。所以你会这样做:
function go() {\n return new Promise((resolve, reject) => {\n setTimeout(() => resolve("Success!"), 500);\n });\n}\n\nconst AS = await go();\nexport default AS; // Or `export { AS };`, but your CJS code was effectively doing `export default`\nRun Code Online (Sandbox Code Playgroud)\n如果需要,您可以合并这些行。对于默认导出
\nexport default await go();\nRun Code Online (Sandbox Code Playgroud)\n对于命名导出:
\nexport const AS = await go();\nRun Code Online (Sandbox Code Playgroud)\n使用您的模块的模块不必知道该AS值来自异步源这一事实;在模块评估完成(承诺解决后)之前,它们不会被评估。他们只是像往常一样导入:
import AS from "./promise.js"; // If it\'s the default export\nconsole.log("AS = " + AS);\nRun Code Online (Sandbox Code Playgroud)\n顶级await在 Node v13+ 中位于--harmony-top-level-await标志后面,并且很快就会进入浏览器。