我似乎无法理解为什么这不起作用。
因为 main
返回一个承诺;所有的 async
函数都是这样。
在顶层,您必须要么:
使用顶级 await
(提案,MDN;ES2022,现代环境下广泛支持)允许在模块中的顶级使用 await
。
或者
使用一个永远不会拒绝的顶级 async
函数(除非您想要“未处理的拒绝”错误)。
或者
使用 then
和 catch
。
#1 在模块中使用顶级 await
您可以在模块的顶层使用 await
。直到您await
的承诺解决(意味着任何等待您的模块加载的模块在承诺解决之前都无法完成加载),您的模块才会完成加载。如果该承诺被拒绝,您的模块将无法加载。通常,在您的模块不能执行其工作直到承诺解决且除非承诺被履行否则完全无法执行其工作的情况下,会使用顶级 await
,这是可以接受的:
const text = await main();
console.log(text);
如果你的模块即使 Promise 被拒绝也能继续工作,那么你可以在顶层的 await
前加上一个 try
/catch
:
try {
const text = await main();
console.log(text);
} catch (e) {
}
当使用顶层
await
的模块被评估时,它会向模块加载器返回一个Promise(就像
async
函数一样),在依赖它的任何模块的主体评估之前等待该Promise完成。
您不能在非模块脚本的顶层使用
await
,只能在模块中使用。
#2 - 顶级
async
函数永不拒绝
(async () => {
try {
const text = await main();
console.log(text);
} catch (e) {
}
})();
注意catch
语句; 你必须处理Promise的拒绝/异步异常,因为没有其他东西会这样做; 你没有调用者可以将它们传递下去(与#1不同,在那里你的“调用者”是模块加载器)。如果你愿意,你可以在通过catch
函数调用它的结果上执行(而不是try
/ catch
语法):
(async () => {
const text = await main();
console.log(text);
})().catch(e => {
});
这样写会更简洁一些,虽然它将 (async
/await
和显式 promise 回调) 进行了混合,通常我不建议这样做。
当然,你也可以选择不处理错误,只允许出现“未处理的拒绝”错误。
#3 - then
和 catch
main()
.then(text => {
console.log(text);
})
.catch(err => {
});
catch
处理程序将在链中或您的then
处理程序中发生错误时调用。 (确保您的catch
处理程序不会引发错误,因为没有注册任何内容来处理它们。)
或者是then
的两个参数:
main().then(
text => {
console.log(text);
},
err => {
}
);
再次注意我们正在注册一个拒绝处理程序。但是在这种形式下,请确保您的then
回调都不会抛出任何错误,因为没有任何内容被注册来处理它们。
await
只是 Promisethen
语法的简化形式。 - Bergimain
。 - Felipenode --experimental-repl-await
。 - nomad