用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

相關文章
相關標籤/搜索