如何在顶层使用 async/await? [英] How can I use async/await at the top level?

查看:63
本文介绍了如何在顶层使用 async/await?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在研究 async/await 并且在阅读了几篇文章之后,我决定自己测试一下.但是,我似乎无法理解为什么这不起作用:

I have been going over async/await and after going over several articles, I decided to test things myself. However, I can't seem to wrap my head around why this does not work:

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):

The console outputs the following (node v8.6.0) :

>外面:[对象承诺]

>内部:嘿嘿

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

Why does the log message inside the function execute afterwards? I thought the reason async/await was created was in order to perform synchronous execution using asynchronous tasks.

有没有办法在main()之后使用函数内部返回的值而不使用.then()?

Is there a way could I use the value returned inside the function without using a .then() after main()?

推荐答案

我似乎无法理解为什么这不起作用.

I can't seem to wrap my head around why this does not work.

因为main 返回一个promise;所有 async 函数都可以.

Because main returns a promise; all async functions do.

在顶层,您必须:

  1. 使用从不拒绝的顶级async 函数(除非您想要未处理的拒绝"错误),或者

  1. Use a top-level async function that never rejects (unless you want "unhandled rejection" errors), or

使用thencatch,或者

(即将推出!) 使用 top-级别await,在流程中已达到第3阶段的提案 允许在模块中顶级使用 await.

(Coming soon!) Use top-level await, a proposal that has reached Stage 3 in the process that allows top-level use of await in a module.

#1 - 永不拒绝的顶级 async 函数

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

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

Notice the catch; you must handle promise rejections / async exceptions, since nothing else is going to; you have no caller to pass them on to. If you prefer, you could do that on the result of calling it via the catch function (rather than try/catch syntax):

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

...更简洁一点(我喜欢这个原因).

...which is a bit more concise (I like it for that reason).

或者,当然,不处理错误,只允许未处理的拒绝"错误.

Or, of course, don't handle errors and just allow the "unhandled rejection" error.

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

如果链中或您的 then 处理程序中发生错误,将调用 catch 处理程序.(确保您的 catch 处理程序不会抛出错误,因为没有注册来处理它们.)

The catch handler will be called if errors occur in the chain or in your then handler. (Be sure your catch handler doesn't throw errors, as nothing is registered to handle them.)

或者 then 的两个参数:

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

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

Again notice we're registering a rejection handler. But in this form, be sure that neither of your then callbacks doesn't throw any errors, nothing is registered to handle them.

您不能在非模块脚本的顶层使用 await,但是 顶级await 提案 (阶段 3) 允许您在模块的顶层使用它.它类似于使用顶级 async 函数包装器(上面的#1),因为您不希望顶级代码拒绝(抛出错误),因为这会导致未处理的拒绝错误.因此,除非您想在出现问题时进行未经处理的拒绝,就像 #1 一样,否则您希望将代码包装在错误处理程序中:

You can't use await at the top level of a non-module script, but the top-level await proposal (Stage 3) allows you to use it at the top level of a module. It's similar to using a top-level async function wrapper (#1 above) in that you don't want your top-level code to reject (throw an error) because that will result in an unhandled rejection error. So unless you want to have that unhandled rejection when things go wrong, as with #1, you'd want to wrap your code in an error handler:

// 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 函数所做的那样),它会等待直到该承诺被解决评估依赖于它的任何模块的主体.

Note that if you do this, any module that imports from your module will wait until the promise you're awaiting settles; when a module using top-level await is evaluated, it basically returns a promise to the module loader (like an async function does), which waits until that promise is settled before evaluating the bodies of any modules that depend on it.

这篇关于如何在顶层使用 async/await?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆