美文网首页
async/await

async/await

作者: 隔壁老王z | 来源:发表于2018-10-30 16:28 被阅读0次

async/await之前的三种写回调的方式:

1、嵌套回调
2、以Promise为主的链式回调
3、使用Generators

但是,这三种写起来都不够优雅,ES7做了优化改进,async/await应运而生,async/await相比较Promise 对象then 函数的嵌套,与 Generator 执行的繁琐(需要借助go才能自动执行,否则得手动调用next() ), Async/Await 可以让你轻松写出同步风格的代码同时又拥有异步机制,更加清晰。

1.async/await更加语义化,async 是“异步”的简写,async function 用于申明一个 function 是异步的; await,可以认为是async wait的简写, 用于等待一个异步方法执行完成;
2.async/await是一个用同步思维解决异步问题的方案(等结果出来之后,代码才会继续往下执行;
3.可以通过多层 async function 的同步写法代替传统的callback嵌套

async function语法
  • 自动将常规函数转换成Promise,返回值也是一个Promise对象;

  • 只有async函数内部的异步操作执行完,才会执行then方法指定的回调函数;

  • 异步函数内部可以使用await

    image.png
await语法
  • await 放置在Promise调用之前,await 强制后面点代码等待,直到Promise对象resolve,得到resolve的值作为await表达式的运算结果;

  • await只能在async函数内部使用,用在普通函数里就会报错;

[return_value] = await expression;

expression:  一个 Promise  对象或者任何要等待的值。

返回值:返回 Promise 对象的处理结果。如果等待的不是 Promise 对象,则返回该值本身。
image.png
错误处理

async函数里,无论是Promise reject的数据还是逻辑报错,都会被默默吞掉,所以最好把await放入try{}catch{}中,catch能够捕捉到Promise对象rejected的数据或者抛出的异常。

function timeout(ms) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {reject('error')}, ms);  //reject模拟出错,返回error
  });
}

async function asyncPrint(ms) {
  try {
     console.log('start');
     await timeout(ms);  //这里返回了错误
     console.log('end');  //所以这句代码不会被执行了
  } catch(err) {
     console.log(err); //这里捕捉到错误error
  }
}

asyncPrint(1000);

如果不用try/catch的话,也可以像下面这样处理错误(因为async函数执行后返回一个promise)。

function timeout(ms) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {reject('error')}, ms);  //reject模拟出错,返回error
  });
}

async function asyncPrint(ms) {
  console.log('start');
  await timeout(ms)
  console.log('end');  //这句代码不会被执行了
}

asyncPrint(1000).catch(err => {
    console.log(err); // 从这里捕捉到错误
});

如果你不想让错误中断后面代码的执行,可以提前截留住错误,像下面

function timeout(ms) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
        reject('error')
    }, ms);  //reject模拟出错,返回error
  });
}

async function asyncPrint(ms) {
  console.log('start');
  await timeout(ms).catch(err => {  // 注意要用catch
console.log(err) 
  })
  console.log('end');  //这句代码会被执行
}

asyncPrint(1000);
使用场景

多个await命令的异步操作,如果不存在依赖关系(后面的await不依赖前一个await返回的结果),用Promise.all()让它们同时触发。

function test1 () {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(1)
        }, 1000)
    })
}

function test2 () {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(2)
        }, 2000)
    })
}

async function exc1 () {
    console.log('exc1 start:',Date.now())
    let res1 = await test1();
    let res2 = await test2(); // 不依赖 res1 的值
    console.log('exc1 end:', Date.now())
}

async function exc2 () {
    console.log('exc2 start:',Date.now())
    let [res1, res2] = await Promise.all([test1(), test2()])
    console.log('exc2 end:', Date.now())
}
exc1();
exc2();

exc1 的两个并列await的写法,比较耗时,只有test1执行完了才会执行test2

在浏览器的Console里尝试一下,会发现exc2的用Promise.all执行更快一些;

image.png

在自己项目中使用可以通过babel来使用。

相关文章

  • async和await

    浅谈Async/Await用 async/await 来处理异步 async和await async:声明一个异步...

  • ES8(一) —— async&await

    目录 async和普通函数的区别 await async/await处理多回调异步 async和await必须配合...

  • async

    async/await特点 async/await更加语义化,async是“异步”的简写,async functi...

  • ES6中的好东西

    1 Await/Async 前端的回调时代我没有赶上,我赶上的是await/async时代。await和async...

  • Vue接口调用方式(三)async/await用法

    async/await用法 1. async/await的基本用法 async/await是ES7引入的新语法,可...

  • nodejs async 使用简介

    async await node async 使用

  • JS 中的 async/await

    async/await 是什么? async/await 是 ES2017 中新增的异步解决方案; await 只...

  • ES2017 async 函数

    async 和 await 在干什么 每个名称都有意义async : 异步await: async wait简...

  • async/await

    async/await async/await 是Generator的语法糖。 Generator 通过将Gene...

  • 小程序-云开发

    async和await async:异步(无等待)await:等待(是为了同步) 一、await 关键字只在 as...

网友评论

      本文标题:async/await

      本文链接:https://www.haomeiwen.com/subject/xgugtqtx.html