我不明白为什么这行不通。
因为主回承诺;所有异步函数都是这样。
在顶层,你必须:
使用顶级等待(提案,MDN;ES2022,在现代环境中广泛支持),允许在模块中顶级使用await。
或
使用从不拒绝的顶级异步函数(除非你想要“未处理的拒绝”错误)。
或
使用then和catch。
模块中的#1顶级await
您可以在模块的顶层使用await。你的模块不会完成加载,直到你等待的承诺解决(意味着任何模块等待你的模块加载不会完成加载,直到承诺解决)。如果承诺被拒绝,您的模块将无法加载。通常,顶级await用于这样的情况:你的模块在承诺被解决之前无法完成它的工作,除非承诺被实现,否则根本无法完成它,所以这很好:
const text = await main();
console.log(text);
如果你的模块可以在promise被拒绝的情况下继续工作,你可以在try/catch中包装顶层的await:
// In a module, once the top-level `await` proposal lands
try {
const text = await main();
console.log(text);
} catch (e) {
// Deal with the fact the chain failed
}
// `text` is not available here
当一个使用顶级await的模块被求值时,它会向模块加载器返回一个promise(就像async函数一样),加载器会一直等待,直到这个promise被确定,然后再计算依赖它的任何模块的主体。
你不能在非模块脚本的顶层使用await,只能在模块中使用。
#2 -从不拒绝的顶级异步函数
(async () => {
try {
const text = await main();
console.log(text);
} catch (e) {
// Deal with the fact the chain failed
}
// `text` is not available here
})();
// `text` is not available here, either, and code here is reached before the promise settles
// and before the code after `await` in the main function above runs
注意其中的陷阱;你必须处理承诺拒绝/异步异常,因为没有其他事情要做;你没有调用者来传递它们(不像上面的#1,你的“调用者”是模块加载器)。如果你愿意,你可以通过catch函数调用它的结果(而不是try/catch语法):
(async () => {
const text = await main();
console.log(text);
})().catch(e => {
// Deal with the fact the chain failed
});
// `text` is not available here, and code here is reached before the promise settles
// and before the code after `await` in the main function above runs
...它更简洁一些,尽管它在某种程度上混合了模型(async/await和显式promise回调),否则我通常建议不要这样做。
当然,也可以不处理错误,只允许出现“未处理的拒绝”错误。
#3 -然后抓住
main()
.then(text => {
console.log(text);
})
.catch(err => {
// Deal with the fact the chain failed
});
// `text` is not available here, and code here is reached before the promise settles
// and the handlers above run
如果链中或then处理程序中发生错误,将调用catch处理程序。(请确保您的catch处理程序不会抛出错误,因为没有注册任何东西来处理它们。)
或者两个论证都是:
main().then(
text => {
console.log(text);
},
err => {
// Deal with the fact the chain failed
}
);
// `text` is not available here, and code here is reached before the promise settles
// and the handlers above run
再次注意,我们注册了一个拒绝处理程序。但是在这种形式中,请确保您的then回调都不会抛出任何错误,因为没有注册任何东西来处理它们。