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变量
- 函数之间存在依赖关系,只有前一个执行完,后面的才会执行,如果队列里面存在长时间消耗的异步任务会导致程序的堵塞,对于非耗时的同步任务则没任何影响