用Promise、Generator、Async函数将异步操做同步化

在平常开发的过程当中总会遇到一些下一个请求须要上一个请求的响应数据做为参数(或者坑爹的小程序开发只能同时最多请求5个),那么这个时候咱们就须要批量地请求一批后再请求一批。ajax

Async函数

首先来介绍一下Async函数方式,Async函数是ES7添加的,目前babel方面已支持,因此能够大胆使用。Async函数最简单,不须要借助其余的执行器便可按照顺序执行。下面来看个例子。小程序

//  正常状况下,await命令后面是一个 Promise 对象。若是不是,会被转成一个当即resolve的 Promise 对象。
async function requestList() {
    let res1 = await new Promise((resolve) => {
        setTimeout(() => {
            resolve('ok');
        }, 100);
    });
    let res2 = await new Promise((resolve) => {
        setTimeout(() => {
            resolve('ok2');
        }, 100);
    });
}

var promise = requestList();

Async函数执行过程当中遇到await就会交出执行权限,等到异步操做完成再进行下面的操做,await 语句返回的是Promise resolve方法的参数。promise

Genrator函数

Genrator函数比起Async函数就像是Async函数是Genrator的语法糖,咱们来看一下。babel

function* gen(){
  try {
    let a = yield new Promise();
    let b = yield new Promise();
    let c = yield new Promise();
  } catch (e) {
    console.log('e');
  }
  yield console.log('c');
}

let g = gen();

执行Generator函数不会像Async函数那样自动执行所有异步操做,而是返回一个执行器,这个执行器有next/throw/return三个方法可让Generator函数里动起来。若是咱们想要向Async函数那样不用本身next next next无止境地调用,那么咱们须要一个自动执行的方法。异步

function go(gen) {
  var g = gen();

  next(g.next());

  function next(res) {
    if (res.done) return value;
    res.value.then((data) => {
      next(g.next(data));
    }).catch((err) => {
      console.error(err);
      next(g.throw(err));
    });
  }
}

Promise

小程序不支持Generator函数,而且同时间最多支持5个请求,因此被迫无奈,只能使用Promise来作异步批量调用。
由于实例化一个Promise对象就会立刻进行异步操做,因此如下的方式是不行的async

let res1 = new Promise();
let res2 = new Promise();
let res3 = new Promise();
let res4 = new Promise();

四个异步操做是同时进行而不是一个接一个进行,如今咱们要同步化这些异步操做怎么作呢?函数

function goPromise(arr) {
  var index = 0;

  run(ajax(arr[index]));

  function run(p) {
    index++;
    p.then((data) => {
      console.log(data);
      if (index < arr.length) {
        run(ajax(arr[index]));
      }
    }).catch((err) => {
      console.error(err);
      if (index < arr.length) {
        run(ajax(arr[index]));
      }
    });
  }
}

很明显就有个弊端,使用promise递归执行异步操做的时候,处理数据的逻辑须要放在递归函数里,就没有Generator函数舒服了,可是有什么办法呢,小程序又不支持Generator函数,又不想引入垫片,就这样作啦。code