前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JavaScript异步函数async\u002Fawait

JavaScript异步函数async\u002Fawait

作者头像
大熊G
发布2022-11-14 16:47:48
4680
发布2022-11-14 16:47:48
举报

theme: channing-cyan

这是我参与8月更文挑战的第14天,活动详情查看:8月更文挑战

异步函数是将期约应用于JavaScript函数的结果。异步函数可以暂停执行,而且不阻塞主线程。异步函数就是async/await,它是Es8新增的。

不知道异步的可以看这个理解异步 (juejin.cn)

async

async关键字用于声明异步函数,它可以在函数声明,函数表达式还有箭头函数上使用。

代码语言:javascript
复制
    async function msg(){}
    let jackson = async function(){}
    let jackson = async ()=>{}

使用async关键字可以让函数具有异步特征,在实际中它需要和await配合使用。

await

一旦定义了一个函数作为一个异步函数,我们就可以使用 await 关键词。这个关键词放在回调的Promise之前,将会暂停执行函数,直到Promise执行或拒绝。

代码语言:javascript
复制
 async function msg(){
        let p = new Promise((resolve,reject)=>setTimeout(resolve,1000,'jackson'));
        console.log(await p);
    }
    msg();//jackson

await 关键字会暂停执行异步函数后面的代码,它这个行为和生成器函数中的yield关键字是一样的,await关键字也是解包对象的值,任何将这个值传给表达式,再用异步恢复异步执行的操作。

停止和恢复执行

来个小栗子,大家看看能不能猜对执行操作,再从中理解一下。

代码语言:javascript
复制
    async function jackson(){
        console.log(await Promise.resolve('jackson'));
    }
    async function bear(){
        console.log(await 'bear');
    }
    async function daxiong(){
        console.log('daxiong');
    }
    jackson();
    bear();
    daxiong();

哈哈哈,其实是倒叙排列的。

await关键字其实很简单,js运行在碰到await关键字时,会记录在哪里暂停执行。等到await右边的值可以使用了,就是处理完回调了,js会向消息列对中推送一个任务,这个任务会恢复异步函数的执行。这样的话,即使await后面跟着一个立即可用的值,函数的其余部分也会被异步求值。

异步函数并不能真正的替代Promise。但两个可以一起携手合作。一个异步函数将 await 执行一个Promise和一个异步函数始终返回一个Promise。

栈追踪和内存管理

期约和异步函数的功能差不多,但他们在内存中的表示差别很大。

代码语言:javascript
复制
    function fooPromiseExecutor(resolve, reject) {
        setTimeout(reject, 1000, 'jackson');
    }

    function foo() {
        new Promise(fooPromiseExecutor);
    }

    foo();

我们可以看到错误信息包含嵌套函数的标识符,那是被调用以创建最初期约实例的函数,其实函数已经返回了,因此栈追踪不应该看到他们。

js引擎会在创建期约时候尽可能保存完整的调用栈,在抛出错误的时候,调用栈可以由运行时的错误处理逻辑数据获取,因而就会出现在栈追踪信息中。这样肯定会占用更多的计算成本和内存。

把以上的例子换成异步函数,我们看一下

代码语言:javascript
复制
 function fooPromiseExecutor(resolve, reject) {
        setTimeout(reject, 1000,'jackson')
    }
    async function foo(){
        await new Promise(fooPromiseExecutor)
    }
    foo();

这样变成异步函数,栈追踪信息救能准确的反应当前的调用栈。fooPromiseExecutor已经返回,所以它不存在错误细腻些中。foo已经被挂起了,并没有退出。js在运行时可以简单嵌套函数中存储指向包含函数的指针,相当于同步函数调用栈一样,它不会像期约那样带来额外的消耗,结果不言而喻,我们在重视性能的时候可以有限考虑异步。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-08-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • theme: channing-cyan
    • async
      • await
        • 停止和恢复执行
          • 栈追踪和内存管理
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档