- 
                Notifications
    You must be signed in to change notification settings 
- Fork 6
Open
Labels
Description
ES6 系列之 Async
ES2017 标准引入了 async 函数,使得异步操作变得更加方便。在异步处理上,async 函数就是 Generator 函数的语法糖。
其实 async 函数的实现原理,就是将 Generator 函数和自动执行器,包装在一个函数里。
async function fn(args) {
  // ...
}
// 等同于
function fn(args) {
  // spawn 函数指的是自动执行器,就比如说 co
  return spawn(function*() {
    // ...
  });
}使用 async 会比使用 Promise 更优雅的处理异步流程。
- 代码更加简洁
function fetch() {
  return (
    fetchData()
    .then(() => {
      return "done"
    });
  )
}
async function fetch() {
  await fetchData()
  return "done"
};- 错误处理
function fetch() {
  try {
    fetchData()
      .then(result => {
        const data = JSON.parse(result);
      })
      .catch(err => {
        console.log(err);
      });
  } catch (err) {
    console.log(err);
  }
}try/catch 能捕获 fetchData() 中的一些 Promise 构造错误,但是不能捕获 JSON.parse 抛出的异常,如果要处理 JSON.parse 抛出的异常,需要添加 catch 函数重复一遍异常处理的逻辑。
async/await 的出现使得 try/catch 就可以捕获同步和异步的错误。
async function fetch() {
  try {
    const data = JSON.parse(await fetchData());
  } catch (err) {
    console.log(err);
  }
}- 调试
因为 then 中的代码是异步执行,所以当你打断点的时候,代码不会顺序执行。而使用 async 的时候,则可以像调试同步代码一样调试。
问题:给定一个 URL 数组,如何实现接口的继发和并发?
async 继发实现:
// 继发一
async function loadData() {
  var res1 = await fetch(url1);
  var res2 = await fetch(url2);
  var res3 = await fetch(url3);
  return "whew all done";
}
// 继发二
async function loadData(urls) {
  for (const url of urls) {
    const response = await fetch(url);
    console.log(await response.text());
  }
}async 并发实现:
// 并发一
async function loadData() {
  var res = await Promise.all([fetch(url1), fetch(url2), fetch(url3)]);
  return "whew all done";
}
// 并发二
async function loadData(urls) {
  // 并发读取 url
  const textPromises = urls.map(async url => {
    const response = await fetch(url);
    return response.text();
  });
  // 按次序输出
  for (const textPromise of textPromises) {
    console.log(await textPromise);
  }
}async 错误捕获:为了简化比较复杂的捕获,我们可以给 await 后的 promise 对象添加 catch 函数:
// to.js
export default function to(promise) {
  return promise
    .then(data => {
      return [null, data];
    })
    .catch(err => [err]);
}
// 使用
[err, user] = await to(UserModel.findById(1));async 会取代 Generator 吗?
Generator 本来是用作生成器,使用 Generator 处理异步请求只是一个比较 hack 的用法,在异步方面,async 可以取代 Generator,但是 async 和 Generator 两个语法本身是用来解决不同的问题的。
async 会取代 Promise 吗?
- async 函数返回一个 Promise 对象
- 面对复杂的异步流程,Promise 提供的 all 和 race 会更加好用
- Promise 本身是一个对象,所以可以在代码中任意传递
- async 的支持率还很低,即使有 Babel,编译后也要增加 1000 行左右。
原文链接:ES6 系列之我们来聊聊 Async