Async/await

JavaScript的异步一直是JavaScript的一个复杂的事,从回调到Promise再到Generator,直到async/await,都是为了解决异步操作带来的麻烦。

先说说async,async是异步的意思,异步就表示不会阻塞代码执行,async写在一个函数声明之前,看个简单的例子:

async function fn() {
    console.log('async方法');
}
console.log('不会阻塞');
console.log('不会阻塞');执行了,所以async是异步的。但是加了async返回的是什么,我们可以console.log(fn())得到:
Promise {<resolved>: undefined}
所以async返回了一个Promise。之前我们讲过Promise,那么我们可以直接调用:
async function fn() {
    return '成功resolve';
}
fn(true).then((res) => {
    console.log(res);
});

这样看来,async好像只是用来生成一个Promise对象,没有什么用,那么这时候就要说一下await了,这两个一般会配套使用,一起出现。需要注意, await 关键字仅仅在 async function中有效。如果在 async function函数体外使用 await ,你只会得到一个语法错误(SyntaxError)。

await会使 async 函数暂停执行,等待 Promise 的结果出来,然后恢复async函数的执行并返回解析值(resolved)。所以await之后需要的是一个Promise对象。

var pro1 = new Promise(function (resolve, reject) {
    setTimeout(function () {
        console.log('正在执行.....');
        resolve('成功1');
        console.log('执行完毕.....');
    }, 2000);
});

var pro2 = new Promise(function (resolve, reject) {
    setTimeout(function () {
        console.log('正在执行.....');
        reject('成功2');
        console.log('执行完毕.....');
    }, 4000);
});

async function fn() {
    var res1 = await pro1;
    console.log(res1);
    var res2 = await pro2;
    console.log(res2);
}

fn();

我们可以看见,Promise对象里面很早就执行了,但是await之后一定会等到Promise成功返回才会向下执行。其中要是有一个返回reject的话也不会向下执行。

这样看起来跟Promise.then很像,但是两者不能混淆:

async function fn() {
    var i = 0;
    setInterval(function () {
        console.log(i++);
    }, 1000);
    var res1 = await pro1;
    console.log(res1);
    var res2 = await pro2;
    console.log(res2);
}

我们可以知道两个计时器是同时调用的,但是第二个计时器还是会在await之后输出,但是这两个计时器是在同一个事件队列进行,时间是根据最耗时的那个方法。而then方法则不是:

var i = 0;
setInterval(function () {
    console.log(i++)
}, 1000);
new Promise(function(resolve, reject){
    setTimeout(function () {
        resolve('star');
    }, 2000);
}).then(function(data){
    return new Promise(function(resolve, reject){
        setTimeout(function () {
            resolve('two result');
        }, 4000);
    });
}).then(function (value) {
    console.log(value);
}).catch(function(err){
    console.log('err: ', err);
});

到最后的输出结果用了6秒,所以两者是不同的。

看起来async/await跟Promise差不多,确实是,在不考虑太多的情况下,使用Promise反而更直接,但是在太多耗时很久的异步下,async/await会是更好的选择,语义也更清晰。

当然,在平时业务开发,很少用到这些,但是不保证会用到的时候。

本文分享自微信公众号 - coding个人笔记(gh_2ce38b49dae1),作者:wade

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-11-21

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • ES6之函数的扩展

    正常情况下没有问题,但是要是a是0或者是false等会被转换成Boolean类型false的时候就会出错。ES6对参数的默认值允许直接设置:

    wade
  • JavaScript深拷贝和浅拷贝

    在JavaScript中操作数据的时候,基础数据类型还好,不管是我们怎么赋值修改都不会有什么问题,但是如果我们操作的是数组或者Object,那很容易出现修改了一...

    wade
  • 立即执行函数

    这两种格式都能保证函数立马执行,这也是立即函数的基础常见的格式,()运算符加上匿名函数,还有另外几种格式也能立即执行:

    wade
  • 大白话 Promise,这到底是干啥用的?

    任何东西不可能凭空出来。那么Promise,它到底是个啥?干嘛用的?为解决什么问题而出现的?咱们以这几个问题为线索,简单的说一下。为什么说是简单说一下呢?因为要...

    web前端教室
  • 谈谈ES6语法(汇总下篇)

    ES2017标准引入了async函数,使得异步操作更加方便。async函数是Generator函数的语法糖。不打算写Generator函数,感兴趣的话可以看文档...

    嘉明
  • 用NW.js构建跨平台桌面应用(4)-数据持久化

    https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API

    江米小枣
  • EXTJS7 publishes将配置属性映射到viewModel

    路过君
  • JavaScript的装逼优化技巧之惰性加载函数

    天下武功唯快不破!编程也是同理!程序的优化,其实最终优化的是代码执行速度。而执行速度的提升往往是从很多代码细节当中不断堆砌出来的。相反,垃圾代码也是同理。

    用户1272076
  • 初学者|手把手带你学TextBlob

    本文介绍了TextBlob的使用方法,这是一个用Python编写的开源的文本处理库。它可以用来执行很多自然语言处理的任务,比如,词性标注,名词性成分提取,情感分...

    用户1737318
  • 初学者|手把手带你学TextBlob

    本文介绍了TextBlob的使用方法,这是一个用Python编写的开源的文本处理库。它可以用来执行很多自然语言处理的任务,比如,词性标注,名词性成分提取,情感分...

    yuquanle

扫码关注云+社区

领取腾讯云代金券