async await详解

版权声明:将遇到的问题,记录下来,方便自己也方便大家。 本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/y491887095/article/details/80807845

首先,await 只能出现在 async 函数中。

1、async 的作用

async 函数负责返回一个 Promise 对象如果在async函数中 return 一个直接量,

async 会把这个直接量通过Promise.resolve() 封装成 Promise 对象;

如果 async 函数没有返回值,它会返回 Promise.resolve(undefined)

2、await 在等待什么

一般我们都用await去等带一个async函数完成,不过按语法说明,
await 等待的是一个表达式,这个表达式的计算结果是 Promise
对象或者其它值。所以,await后面实际可以接收普通函数调用或者直接量。

如果await等到的不是一个promise对象,那跟着的表达式的运算结果就是它等到的东西;

如果是一个promise对象,await会阻塞后面的代码,等promise对象resolve,

得到resolve的值作为await表达式的运算结果虽然await阻塞了。

resolve的值,就相当于then中的val。

但await在async中,async不会阻塞,它内部所有的阻塞都被封装在一个promise对象中异步执行。当遇到await时,他会先让出当前线程,将后面的代码加到任务队列中,然后继续执行函数后面的同步代码。

不理解?看下面的演示代码:


async function async1() {
  console.log("a");
  //执行这一句后,await会让出当前线程,
  //将后面的代码加到任务队列中,然后继续执行函数后面的同步代码
  await  async2();
  console.log("b");

}

async function async2() {
  console.log( 'c');
}

console.log("d");

setTimeout(function () {
  console.log("e");
},0);

async1();

new Promise(function (resolve) {
  console.log("f");
  resolve();
}).then(function () {
  console.log("g");
});

console.log('h');

参考答案:

node端的答案:// d a c f h b g e

浏览器端的答案:// d a c f h g b e

3、async 函数对 Generator 函数的改进,体现在以下三点。

(1)内置执行器。 Generator 函数的执行必须靠执行器,所以才有了 co 函数库,而 async 函数自带执行器。也就是说,async 函数的执行,与普通函数一模一样,只要一行。

var result =async ReadFile();

(2)更好的语义。 async 和 await,比起星号和 yield,语义更清楚了。async 表示函数里有异步操作,await 表示紧跟在后面的表达式需要等待结果。

(3)更广的适用性。 co 函数库约定,yield 命令后面只能是 Thunk 函数或 Promise 对象,而 async 函数的 await 命令后面,可以跟 Promise 对象和原始类型的值(数值、字符串和布尔值,但这时等同于同步操作)。

4、async await错误处理的方式

对于async/await的模式,如果在try…catch语句中不使用await关键字,那么try…catch子句不会真正工作。

async function check(){
    let promises = _.map(rules, async(rule) => {
        throw new Error('aaaaaa');
    });
    return await Promise.all(promises);
}

async function doCheck(){
    let result;
    try{
         result = await check();
    }
    catch(e){
        console.log('error occurs');
    }  
}

为了让异常捕获更加简单,我们使用Bounce模块,它提供了一个background()方法。

const Bounce = require('bounce');
Bounce.background(() => email(user, message));

还有一种方式是,在await后的Promise添加catch回调。

await read('1.txt','utf8').catch(function(err){
    console.log(err);
})

5、更多demo

function takeLongTime(n) {
  return new Promise(resolve => {
    setTimeout(() => resolve(n + 200), n);
  });
}

function step1(n) {
  console.log(`step1 with ${n}`);
  return takeLongTime(n);
}

function step2(n) {
  console.log(`step2 with ${n}`);
  return takeLongTime(n);
}

function step3(n) {
  console.log(`step3 with ${n}`);
  return takeLongTime(n);
}

 function c() {
  return Promise.resolve(3000);
}

async function doIt() {
  console.time("doIt");
  const time1 = 300;
  let timeb = await c();
  console.log(0,timeb);

  const time2 = await step1(time1);
  console.log(1,time2);

  const time3 = await step2(time2);
  console.log(2,time3);

  const result = await step3(time3);
  console.log(3,result);

  console.log(`result is ${result}`);
  console.timeEnd("doIt");
}

doIt();

//输出结果
0 3000
step1 with 300
1 500
step2 with 500
2 700
step3 with 700
3 900
result is 900
doIt: 1505.812ms

参考链接:

Bounce

理解 JavaScript 的 async/await

Async +Await

猜你喜欢

转载自blog.csdn.net/y491887095/article/details/80807845