一、async/await介绍


01.简介


async关键字是ES7的一部分,async定义在函数声明之前,使函数变成异步函数,其返回一个Promise对象; await关键字用于等待一个Promise对象,它只能在async函数中才起作用。 通过使用它们,异步代码看起来更像是老式同步代码。 有关【promise】的知识请点击下方链接:

【promise】:JS中异步编程解决方案Promise

function fn() {    return new Promise((resolve, reject) => {        resolve(Math.random())    });}(async function asyncFn() {    var random1 = await fn();    console.log(random1);    var random2 = await fn();    console.log(random2);})()

如上,使用async/await并不需要回调嵌套,也不需要写多个then方法,在使用上甚至类似一个同步操作。

02.async


在函数声明前添加async关键字,使函数变成异步函数。async函数返回一个Promise对象,可以使用then方法添加回调函数。

例如在函数asyncFn前添加async 关键字,此时asyncFn就是一个异步函数,会返回Promise对象。

async function asyncFn(a) {    return a;}asyncFn(123).then((data) => {    console.log(data); // 123}).catch((e) => {    console.log(e);})

03.await



await 关键字会暂停异步函数的执行,并等待Promise执行,然后继续执行异步函数,并返回结果。

async function asyncFn(a,b) {    const aResult = await Promise.resolve(a); // 1    const bResult = await Promise.resolve(b) + aResult; // 2 + 1 = 3    return aResult + bResult}asyncFn(1,2).then((data) => {    console.log(data); // 4}).catch((e) => {    console.log(e);})

如上,此时Promise.resolve(a) 和 await Promise.resolve(b)就类似于两个请求方法。以往的异步中要么使用嵌套的方式,在回调函数中接受aResult值再调用下一个方法,要么运用Promise在then方法里调到。await关键字解决了Promise书写多个then的不便。

await 只在异步函数里面才起作用,如果await操作符后的表达式的值不是一个Promise,则返回该值本身。

function fn() {    return 1;}async function asyncfn() {    var result = await fn();    console.log(result); // 1}asyncfn()


二、async/await和try...catch一起使用

Promise函数有成功和失败的返回值resolve和reject,使用then() 处理成功的返回值、catch() 方法处理异常情况的返回值,而对于await语句,则需要放置于 try...catch代码块中,这样可以在catch里捕捉错误信息。

function fn() {    return new Promise((resolve, reject) => {        resolve(Math.random())    });}(async function asyncFn() {    try {        var random1 = await fn();        console.log(random1);        var random2 = await fn();        console.log(random22);    } catch (e) {        console.log(e) // ReferenceError: random22 is not defined    }})()


三、async/await缺点

async/await虽然比Promise的then方式优化了很多,但是如果有大量的await的promises相继发生程序会变慢。如果想要所有的promises同时开始处理,最后才返回结果,此时可以借助setTimeout伪造异步进程;

  • 定义一个函数fn,传入参数num,return一个Promise对象,并间隔1s调用resolve方法把num值返回;
  • 然后,定义一个async的test方法,在test里调用方法fn,并依次传入实参1,2,3,并调用test方法;
  • 最后,间隔3s后 1,2,3被同时输出。

此时就实现了用同步的方法,调用异步的函数。

function fn(num){    return new Promise((resolve,reject) => {        setTimeout( () => {            resolve(num)        }, 1000)    })}async function test(){    let a = await fn(1)    let b = await fn(2)    let c = await fn(3)    console.log(a,b,c) // 1 2 3}test()


四、async/await是generator的语法糖

async函数把Generator里的*替换成 async,将 yield 替换成 await。

定义一个函数fn,接受参数num

function fn(num) {    return new Promise((resolve, reject) => {        resolve(console.log(num))    })}


写一个Generator依次调用传递的参数

function *testGen(){    fn(1)    yield    fn(2)    yield    fn(3)}let f = testGen()f.next() f.next() f.next() // 1 2 3


async函数的写法

async function test() {    let a = await fn(1)    let b = await fn(2)    let c = await fn(3)}test() // 1 2 3


我们发现async函数把testGen里的*替换成 async,将 yield 替换成 await而已。

 ◆ ◆


References


https://developer.mozilla.org/zh-CN/docs/learn/JavaScript/%E5%BC%82%E6%AD%A5/Async_await

mdn

 ◆ ◆

await axios处理异常 await怎么捕获异常_返回结果


Readings


      有些职业,比如牙医、咨询师和按摩师的收入是不可能具有突破性的:它们受到在既定的时间内服务的病人或客户的最大数量的限制。如果 你开一家美味的餐厅,你最多只能逐步扩大生意规模(除非连锁经营)。在这些职业中,不论报酬多高,你的收入总是受到限制的。

      还有一些职业,如果你干得好的话,能让你的产出(以及收入)十倍、百倍地增长,同时几乎或者完全不需要额外的努力。

      一位作家吸引一名读者与吸引数亿读者需要花费的努力是一样的。《哈利·波特》的作者J·K·罗琳不必在每次有人想读这本书的时候都写一遍。但面包师做不到——他必须为每一位新客户——烤出面包。

书名:黑天鹅:如何应对不可预知的未来(升级版)作者:【美】塔勒布

END