文章原文連接地址: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個樹叉的結果集合。
