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

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方法的参数。

Genrator函数

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

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对象就会马上进行异步操作,所以以下的方式是不行的

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函数,又不想引入垫片,就这样做啦。


一画先生
83 声望12 粉丝

我司长期招聘前端开发工程师,有意的小伙伴+vx: Mr_yihua