理解與使用Promise完成復雜異步處理流程


文章原文連接地址:https://blog.csdn.net/qq120848369/article/details/53204435

 

本文談到的Promise是指javascript環境下的Promise,然而Promise這個功能在若干語言中均有實現,我本次會在Nodejs服務端環境下進行學習和理解。

Promise是為了解決日趨復雜的異步程序設計而出現的,簡單的異步例如:發起一個ajax請求來獲取數據,之后渲染DOM。

然而現實世界並沒有這么簡單,我們極有可能需要同時發起多個ajax請求並等待它們全部返回,在獲得結果后可能又需要根據上一輪的數據發起下一輪的ajax獲取其他數據,這樣的流程完全可以演變得交織錯雜,編程和維護起來是非常頭疼的。

此前,我們解決這種問題就是callback的回調思路,callback嵌套callback的代碼層出不窮,想追加點功能需要一層一層的數括號,這就急需一個替代方案的出現。

new Promise(function(resolve,reject){
	resolve();
})
.then(data => {
    // promise start
    console.log('result of start: ', data);
    return Promise.resolve(1); // p1
  })
  .then(data => {
    // promise p1
    console.log('result of p1: ', data);
    return Promise.reject(2); // p2
  })
  .then(data => {
    // promise p2
    console.log('result of p2: ', data);
    return Promise.resolve(3); // p3
  })
  .catch(ex => {
    // promise p3
    console.log('ex: ', ex);
    return Promise.resolve(4); // p4
  })
  .then(data => {
    // promise p4
    console.log('result of p4: ', data);
  });

result of start:  start
result of p1:  1
ex:  2
result of p4:  4

 

終止鏈式: 

終止鏈式:
new Promise(function(resolve,reject){
	resolve();
})
.then(data => {
    // promise start
    console.log('result of start: ', data);
    return Promise.resolve(1); // p1
  })
  .then(data => {
    // promise p1
    console.log('result of p1: ', data);
    return Promise.reject({  //終止鏈式
      notRealPromiseException: true,
    }); // p2
  })
  .then(data => {
    // promise p2
    console.log('result of p2: ', data);
    return Promise.resolve(3); // p3
  })
  .catch(ex => {
    // promise p3
    console.log('ex: ', ex);
    if (ex.notRealPromiseException) {
      // 一切正常,只是通過 catch 方法來中止 promise chain
      // 也就是中止 promise p2 的執行
      return true;
    }
    // 真正發生異常
    return false;
  })

  

 

 

new Promise( /* executor */ function(resolve, reject) { ... } );
這個函數提供了2個function給業務調用,調用Resolve就可以改變這個Promise的狀態為resolved,同樣道理調用reject就可以讓Promise的狀態變為rejected。

// 同步reject
var promise2 = new Promise(
    (resolve, reject) => {
        reject("this is promise2 reject");
    }
).then(
    (msg) => {
        console.log(msg);
    },
    (err) => {
        console.log(err);
    }
);

 

// 鏈式resolve
var promise5 = new Promise(
    (resolve, reject) => {
        var promise4_1 = new Promise(
            (resolve, reject) => {
                console.log("promise5_1 starts");
                setTimeout(
                    () => {
                        resolve("this is promise5_1 resolve");
                    },
                    2000
                );
            }
        );
        resolve(promise4_1);
    }
).then(
    (msg) => {
        console.log(msg);
        var promise5_2 =  new Promise(
            (resolve, reject) => {
                console.log("promise5_2 starts");
                setTimeout(
                    () => {
                        resolve("this is promise5_2 resolve");
                    },
                    2000
                );
            }
        );
        return promise5_2;
    }
).then(
    (msg) => {
        console.log(msg);
        throw new Error();
    }
).catch(
    () => {
        console.log("exception catched after promise5_2 resolved");
    }
);
這個例子變得再復雜一些,除了在promise5中節外生枝promise5_1異步處理2秒,在2秒后回到主干后的.then()環節,我通過return返回一個Promise對象再次節外生枝promise5_2異步執行2秒,之后再次回到主干的.then()打印出消息並且拋出了異常,最終由catch捕獲。


// 並行+鏈式promise
var promise6 = new Promise(
    (resolve, reject) => {
        var promiseArr = [];
        for (var i = 0; i < 5; ++i) {
            promiseArr.push(new Promise(
                (resolve, reject) => {
                    console.log(`promise6_${i} starts`);
                    ((index) => { // 閉包處理i
                        setTimeout(
                            () => {
                                console.log(`before promise6_${index} resolved`);
                                resolve(`this is promise6_${index} resolve`);
                            },
                            index * 1000
                        );
                    })(i);
                }
            ));
        }
        resolve(Promise.all(promiseArr));
    }
).then(
    (msgArr) => {
        console.log(`promise6 all resolved ${msgArr}`);
    }
);

這個例子主要是體驗Promise.all(),這個函數其實創建返回了一個Promise對象,內部管理與並發了多個Promise流程(節外生枝了N個樹叉),它等待它們全部完成或者任意失敗之后會終結自己,在外層通過resolve將Promise.all()返回的集合式Promise對象串聯(托管)起來,最終進入下一個then從而可以訪問N個樹叉的結果集合。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM