const p = Promise.all([p1, p2, p3]);
p的狀態由p1,p2,p3控制,只有所有都resolve才能在then裏面獲取到所有結果,如果其中一個reject就返回前一個元素的resolve
A.有時候即使其中一個reject了我們希望其他的仍舊可以繼續執行並且獲取到結果
例如:
如果P1,resove就返回數據 {data:response,succ:true}
如果P1,reject就返回數據{data:null,succ:false,err:{...}}
succ是用來判斷該數據是否成功,err裏面包含錯誤信息方便我們進行處理
代碼實現如下:
var arr = [];//函數鏈,
var result = [];//結果
for (let i = 0; i < 5; i++) {
arr.push({
resolve: () => {
if (i % 2 == 0) {
return new Promise((resolve, reject) => {
let t={data:{i:i},succ:true};
result.push(t)
resolve(t);
})
}
else {
let t={data:{i:"resolve裏面的reject"+i},succ:false,error:"error message"};
result.push(t)
//這裏不應該reject否則會被下一個原生的reject捕獲到
//我們這個程序裏面不需要用到reject函數,所有reject都通過數據succ來做反應
return Promise.resolve(t);
}
},
reject: (e) => {
let t={data:{i:i},succ:false,error:"error message"};
result.push(t)
return Promise.resolve({ data: result,error:"reject的信息" })
}
})
}
let promise = Promise.resolve({ data: "1" });
while (arr.length) {
let { resolve, reject } = arr.shift();
console.log(resolve, reject)
/**
* then方法的第一個參數是resolved狀態的回調函數,
* 第二個參數(可選)是rejected狀態的回調函數。
*/
/**
* then方法返回的是一個新的Promise實例(注意,不是原來那個Promise實例)。
* 因此可以採用鏈式寫法,即then方法後面再調用另一個then方法。
*/
promise = promise.then(resolve, reject)
}
promise.then((resolve, reject) => {
console.log("結果", result,JSON.stringify(result)) // {data: 6,respone:{code:0}}
}).catch(e=>{
console.log("err",e)
})
最後輸出的result結果如下:
[
{
"data": {
"i": 0
},
"succ": true
},
{
"data": {
"i": "resolve裏面的reject1"
},
"succ": false,
"error": "error message"
},
{
"data": {
"i": 2
},
"succ": true
},
{
"data": {
"i": "resolve裏面的reject3"
},
"succ": false,
"error": "error message"
},
{
"data": {
"i": 4
},
"succ": true
}
]
得到所有結果,如果是失敗,succ就是false,並且攜帶錯誤信息
到此解決A需求
但是這個程序也存在弊端:
- 需要額外添加result變量
- 函數之間存在依賴關係,只有前一個執行完,後面的纔會執行,如果隊列裏面存在長時間消耗的異步任務會導致程序的堵塞,對於非耗時的同步任務則沒任何影響