欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

async/await的用法

程序员文章站 2022-03-11 19:00:04
async/await的用法asyncasync/await实际上是Generator的语法糖。顾名思义,async关键字代表后面的函数中有异步操作,await表示等待一个异步方法执行完成。声明异步函数只需在普通函数前面加一个关键字async即可,如:async function test() {}async 函数返回一个Promise对象(如果指定的返回值不是Promise对象,也返回一个Promise,只不过立即 resolve ,处理方式同 then 方法),因此 async 函数通...

async/await的用法

  • async

async/await实际上是Generator的语法糖。顾名思义,async关键字代表后面的函数中有异步操作,await表示等待一个异步方法执行完成。声明异步函数只需在普通函数前面加一个关键字async即可,如:

async function test() {}

async 函数返回一个Promise对象(如果指定的返回值不是Promise对象,也返回一个Promise,只不过立即 resolve ,处理方式同 then 方法),因此 async 函数通过 return 返回的值,会成为 then 方法中回调函数的参数:

async function test() {
  return 'hello!';
}

test().then(value => {
  console.log(value);
})
// hello!

单独一个 async 函数,其实与Promise执行的功能是一样的,下面介绍await的作用。

  • await

await 就是异步等待,它等待的是一个Promise,因此 await 后面应该写一个Promise对象,如果不是Promise对象,那么会被转成一个立即 resolve 的Promise。 async 函数被调用后就立即执行,但是一旦遇到 await 就会先返回,等到异步操作执行完成,再接着执行函数体内后面的语句。总结一下就是:async函数调用不会造成代码的阻塞,但是await会引起async函数内部代码的阻塞。看看下面这个例子:

async function func() {
  console.log('async function is running!');
  const num1 = await 200;
  console.log(`num1 is ${num1}`);
  const num2 = await num1+ 100;
  console.log(`num2 is ${num2}`);
  const num3 = await num2 + 100;
  console.log(`num3 is ${num3}`);
}

func();
console.log('run me before await!');
// async function is running!
// run me before await!
// num1 is 200
// num2 is 300
// num3 is 400

可以看出调用 async func 函数后,它会立即执行,首先输出了’async function is running!’,接着遇到了 await 异步等待,函数返回,先执行func()后面的同步任务,同步任务执行完后,接着await等待的位置继续往下执行。可以说,async函数完全可以看作多个异步操作,包装成的一个Promise 对象,而await命令就是内部then命令的语法糖。

值得注意的是, await 后面的 Promise 对象不总是返回 resolved 状态,只要一个 await 后面的Promise状态变为 rejected ,整个 async 函数都会中断执行,为了保存错误的位置和错误信息,我们需要用 try…catch 语句来封装多个 await 过程,如下:

async function func() {
  try {
    const num1 = await 200;
    console.log(`num1 is ${num1}`);
    const num2 = await Promise.reject('num2 is wrong!');
    console.log(`num2 is ${num2}`);
    const num3 = await num2 + 100;
    console.log(`num3 is ${num3}`);
  } catch (error) {
    console.log(error);
  }
}

func();
// num1 is 200
// 出错了
// num2 is wrong!

如上所示,在 num2 处 await 得到了一个状态为 rejected 的Promise对象,该错误会被传递到 catch 语句中,这样我们就可以定位错误发生的位置。

  • async/await比Promise强在哪儿?

  • promise的链式调用:
function sayHi(name) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(name);
    }, 2000)
  })
}

sayHi('张三')
  .then(name => {
    console.log(`你好, ${name}`);
    return sayHi('李四');    // 最终 resolved 函数中的参数将作为值传递给下一个then
  })
  // name 是上一个then传递出来的参数
  .then(name => {                
    console.log(`你好, ${name}`);
    return sayHi('王二麻子');
  })
  .then(name => {
    console.log(`你好, ${name}`);
  })
// 你好, 张三
// 你好, 李四
// 你好, 王二麻子
  • async/await的链式调用:
function sayHi(name) {
  return new Promise((resolved, rejected) => {
    setTimeout(() => {
      resolved(name);
    }, 2000)
  })
}

async function sayHi_async(name) {
  const sayHi_1 = await sayHi(name)
  console.log(`你好, ${sayHi_1}`)
  const sayHi_2 = await sayHi('李四')
  console.log(`你好, ${sayHi_2}`)
  const sayHi_3 = await sayHi('王二麻子')
  console.log(`你好, ${sayHi_3}`)
}

sayHi_async('张三')
// 你好, 张三
// 你好, 李四
// 你好, 王二麻子

与promise的then链和then方法里的回调函数相比,asunc/await的写法看起来像是同步写法并且更加清爽,更加符合编程习惯。

本文地址:https://blog.csdn.net/qq_33286909/article/details/107897140