首页 > 其他 > 详细

async、await

时间:2019-05-09 15:18:56      阅读:165      评论:0      收藏:0      [点我收藏+]

async / await是ES7的重要特性之一,也是目前社区里公认的优秀异步解决方案。目前,async / await这个特性已经是stage 3的建议。

(1)Promise、generator、yield是ES6中的异步解决方案,使用Promise之后,可以很好的减少嵌套的层数。

function fn(p) {
  return new Promise((resolve, reject) => {
    console.log(p);
    setTimeout(() => {
      console.log(‘test:‘,p);
      resolve();
    }, 2000);
  });
}

    function handlePromise() {
      fn("aaa")
        .then(() => {
          return fn("bbb");
        })
        .then(() => {
          return fn("ccc");
        })
        .catch(reason => console.log(`catch reason: ${reason}`));
    }

执行:handlePromise()

Promise仍然存在缺陷,它只是减少了嵌套,并不能完全消除嵌套。对于多个promise串行执行的情况,第一个promise的逻辑执行完之后,我们需要在它的then函数里面去执行第二个promise,这个时候会产生一层嵌套。另外,采用Promise的代码看起来依然是异步的!

(2)在Node.js中对于回调的处理,我们经常用的TJ / Co就是使用generator结合promise来实现的,co是coroutine的简称。

const co = require(‘co‘);
const request = require(‘request‘);

const options = {
  url: ‘https://api.github.com/repos/cpselvis/zhihu-crawler‘,
  headers: {
    ‘User-Agent‘: ‘request‘
  }
};
// yield后面是一个生成器 generator
const getRepoData = function* () {
  return new Promise((resolve, reject) => {
    request(options, (err, res, body) => {
      if (err) {
        reject(err);
      }
      resolve(body);
    });
  });
};

co(function* () {
  const result = yield getRepoData;
  // ... 如果有多个异步流程,可以放在这里,比如
  // const r1 = yield getR1;
  // const r2 = yield getR2;
  // const r3 = yield getR3;
  // 每个yield相当于暂停,执行yield之后会等待它后面的generator返回值之后再执行后面其它的yield逻辑。
  return result;
}).then(function (value) {
  console.log(value);
}, function (err) {
  console.error(err.stack);
});

(3)虽然co是社区里面的优秀异步解决方案,但是并不是语言标准,只是一个过渡方案。

ES7语言层面提供async / await去解决语言层面的难题。目前async / await 在 IE edge中已经可以直接使用了,但是chrome和Node.js还没有支持。

幸运的是,babel已经支持async的transform了,所以我们使用的时候引入babel就行。

在开始之前我们需要引入以下的package,preset-stage-3里就有我们需要的async/await的编译文件。

无论是在Browser还是Node.js端都需要安装下面的包。

$ npm install babel-core --save
$ npm install babel-preset-es2015 --save
$ npm install babel-preset-stage-3 --save
function fn(p) {
  return new Promise((resolve, reject) => {
    console.log(p);
    setTimeout(() => {
      console.log(‘test:‘,p);
      resolve();
    }, 2000);
  });
}
// 注意点:
// 1.async用来申明里面包裹的内容可以进行同步的方式执行,await则是进行执行顺序控制,
// 每次执行一个await,程序都会暂停等待await返回值,然后再执行之后的await。
// 2.await后面调用的函数需要返回一个promise,另外这个函数是一个普通的函数即可,而不是generator。
// 3.await只能用在async函数之中,用在普通函数中会报错。
// 4.await命令后面的 Promise 对象,运行结果可能是 rejected,所以最好把 await 命令放在 try...catch 代码块中。
// 5.其实,async / await的用法和co差不多,await和yield都是表示暂停,
// 外面包裹一层async 或者 co来表示里面的代码可以采用同步的方式进行处理。
// 不过async / await里面的await后面跟着的函数不需要额外处理,co是需要将它写成一个generator的。
async function asyncFun() {
 try {
    const result_a = await fn(‘aaa‘);
    const result_b = await fn(‘bbb‘);
    const result_c = await fn(‘ccc‘);
    const result_d = await fn(‘ddd‘);
    // 每个await相当于暂停,执行await之后会等待它后面的函数(不是generator)返回值之后再执行后面其它的await逻辑。
    return result_d;
  } catch (err) {
    console.log(err);
  }
}
执行:asyncFun().then(result => console.log(`result: ${result}`)).catch(err => console.error(err));

参考:

http://www.cnblogs.com/cpselvis/p/6344122.html

http://caibaojian.com/es6/generator.html

 

async、await

原文:https://www.cnblogs.com/fengyouqi/p/10838573.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!