一尘不染

如何在顶层使用异步/等待?

node.js

我已经浏览了async/ await在浏览了几篇文章之后,我决定自己测试一下。但是,我似乎无法解决为什么它不起作用的问题:

async function main() {  
    var value = await Promise.resolve('Hey there');
    console.log('inside: ' + value);
    return value;
}

var text = main();  
console.log('outside: ' + text);

控制台输出以下内容(节点v8.6.0):

外部:[对象承诺]

内部:嘿

为什么函数内部的日志消息随后执行?我认为创建async/ 的原因await是为了使用异步任务执行同步执行。

有没有办法可以使用函数内部返回的值而不使用.then()after main()


阅读 252

收藏
2020-07-07

共1个答案

一尘不染

我似乎无法绕开为什么这行不通的想法。

因为main回报承诺;所有async功能都可以。

在顶层,您必须:

  1. 使用async永不拒绝的顶层函数(除非您希望出现“未处理的拒绝”错误),或者

  2. 使用thencatch,或

  3. (即将推出!) 使用顶层await,该提案已进入允许在模块中顶层使用的过程中的第3阶段await

#1- async永不拒绝的顶级功能

(async () => {
    try {
        var text = await main();
        console.log(text);
    } catch (e) {
        // Deal with the fact the chain failed
    }
})();

注意catch; 您 必须
处理promise拒绝/异步异常,因为没有其他事情可做;您没有呼叫者将其传递给。如果愿意,可以在通过catch函数调用它的结果上执行此操作(而不是try/
catch语法):

(async () => {
    var text = await main();
    console.log(text);
})().catch(e => {
    // Deal with the fact the chain failed
});

…更加简洁(出于这个原因,我喜欢)。

或者,当然,不处理错误,而只允许“未处理的拒绝”错误。

#2- thencatch

main()
    .then(text => {
        console.log(text);
    })
    .catch(err => {
        // Deal with the fact the chain failed
    });

catch如果发生在链中或在你的错误处理程序将调用then处理程序。(请确保您的catch处理程序不会抛出错误,因为没有任何内容可以处理。)

或两个参数都then

main().then(
    text => {
        console.log(text);
    },
    err => {
        // Deal with the fact the chain failed
    }
);

再次注意,我们正在注册一个拒绝处理程序。但是,以这种形式,请确保您的then回调都不会引发任何错误,也没有任何内容可处理。

#3顶级await模块

您不能await在非模块脚本的顶层使用await,但是顶层建议第3阶段)允许您在模块的顶层使用它。这与使用顶级async函数包装器(上面的#1)相似,因为您不希望顶级代码拒绝(抛出错误),因为这将导致未处理的拒绝错误。因此,除非您要在出现问题时(例如#1)遇到未处理的拒绝,否则您要将代码包装在错误处理程序中:

// In a module, once the top-level `await` proposal lands
try {
    var text = await main();
    console.log(text);
} catch (e) {
    // Deal with the fact the chain failed
}

请注意,如果执行此操作,则从模块导入的任何模块都将等待,直到您履行的诺言await得以兑现;当await评估使用顶层的模块时,它基本上会向模块加载器返回一个承诺(就像async函数一样),该加载器会等到该承诺得到解决,然后再评估依赖于该模块的任何模块的主体。

2020-07-07