为了账号安全,请及时绑定邮箱和手机立即绑定

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

/ 猿问

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

萧十郎 2019-12-18 16:33:06

我一直在浏览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()?


查看完整描述

3 回答

?
慕容708150

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


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


在顶层,您必须:


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


使用then和catch,或


(即将推出!)使用顶层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- then和catch

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

}


查看完整回答
反对 回复 2019-12-18
?
四季花海

顶层await已进入阶段3,因此您问题的答案如何在顶层使用async / await?就是将await通话添加到main():


async function main() {  

    var value = await Promise.resolve('Hey there');

    console.log('inside: ' + value);

    return value;

}


var text = await main();  

console.log('outside: ' + text)

要不就:


const text = await Promise.resolve('Hey there');

console.log('outside: ' + text)

请记住,它仍然仅在Webpack@v5.0.0-alpha.15中可用。


如果您使用的是TypeScript,它可能会安装在3.8中。


v8 增加了对模块的支持。



查看完整回答
反对 回复 2019-12-18
?
波斯汪

解决此问题的实际方法是采用不同的方法。


您的目标可能是某种初始化,通常发生在应用程序的顶层。


解决方案是确保应用程序的顶层仅存在一个JavaScript语句。如果您的应用程序顶部只有一条语句,那么您可以在其他任何地方随意使用async / await(当然要遵循常规语法规则)


换句话说,将整个顶层包装在一个函数中,使其不再是顶层,并且解决了如何在应用程序的顶层运行异步/等待的问题,而您却没有。


这是应用程序的顶层外观:


import {application} from './server'


查看完整回答
反对 回复 2019-12-18

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信