有没有办法让 javascript
await
关键字在 async
函数之外工作?我希望能够冻结整个调用堆栈(而不仅仅是 async
函数的其余部分),以便在特定 Promise 返回值后恢复。遗憾的是,像这样强大的await
目前还没有实现或还没有实现。我尝试让 nodent.js 工作,但由于我的自定义加载程序和动态函数,不幸的是它不切实际。
有没有办法让 javascript wait 关键字在异步函数之外工作?
可悲的是,答案是:不。
请参阅文档:
await 表达式会导致异步函数执行暂停,等待 Promise 的解析,并在解析值时恢复异步函数执行。 [已添加强调]
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await
我希望能够冻结整个调用堆栈(而不仅仅是异步函数的其余部分),以便在特定 Promise 返回值后恢复。
但是如果整个调用堆栈都被冻结了,你的 Promise 如何返回一个值呢?它将永远被卡住。
要使用
await
,您需要在async function
内。
至少你必须做:
async function main() {
// use await here
}
main();
在你的主代码中。
或者,使用 IIFE - 感谢 Robert Klep 的建议:
void async function main() {
// use await here
}();
或者,如果您喜欢标点符号:
(async () => {
// use await here
})();
还有一些其他选项可以处理 Node 中的并发,例如:
但是,这些都不会冻结调用堆栈,因为它与使用您自己的进程 ID 运行
kill -STOP
并等待已停止的进程自行恢复具有相同的效果。
鉴于您正在寻找一种 hack,而不是一个合适的基于承诺的并发解决方案,请查看 node-fibres (有类似的解决方案,但据我所知,这是最流行的,围绕它构建了多个抽象)。它确实允许您停止任何同步函数中的当前纤程,直到发生在不同纤程中运行的异步事件。这当然是一个可怕的想法,但是……
是...是...是,现在在 javascript 中是可能的。
顶级await已在ES13中引入。现在您可以在没有
await
的情况下享受 async
的好处。您可能需要 Babel 来转换下一代 JavaScript。
//The old behavior
await Promise.resolve(console.log('Hello World'));
// Output: SyntaxError: await is only valid in async function
// Alternative to fix the problem
(async function() {
await Promise.resolve(console.log('Hello World'));
// Output: Hello World
}());
// The New behavior
await Promise.resolve(console.log('Hello World')); // → Hello World
//Dynamic dependency pathing
const strings = await import(`/i18n/${navigator.language}`);
//Resource initialization
const connection = await dbConnector();
// Dependency fallbacks
let jQuery;
try {
jQuery = await import('https://cdn-a.com/jQuery');
} catch {
jQuery = await import('https://cdn-b.com/jQuery');
}
更多信息:
https://github.com/opensrc0/es-features?tab=readme-ov-file#ES2022-ES13