The introduction
This paper introduces promise.Allsettled content step by step from four aspects:
Promise.all()
The defects of- The introduction of
Promise.allSettled()
Promise.allSettled()
与Promise.all()
Applicable scenarios- handwritten
Promise.allSettled()
implementation
The following text begins 👇
Promise. All the defects of ()
As we explained in a previous article, when we execute a Promise using promise.all (), we reject any Promise that fails, rejecting the first error message thrown. The success callback in.then is called only if all promises are resolved
const p1 = Promise.resolve(1)
const p2 = Promise.resolve(2)
const p3 = new Promise((resolve, reject) = > {
setTimeout(reject, 1000.'three');
});
Promise.all([p1, p2, p3])
.then(values= > {
console.log('resolve: ', values)
}).catch(err= > {
console.log('reject: ', err)
})
// reject: three
Copy the code
Note: Any one of thempromise
被 reject
,Promise.all
Would have been immediatelyreject
, other unfinished items in the arraypromise
It’s still being implemented,Promise.all
No steps have been taken to cancel their implementation
In most scenarios, however, we expect the incoming set of promises to obtain the execution result of each promise regardless of failure or success. To this end, ES2020 introduces promise.Allsettled ()
Promise.allSettled()
Promise.allsettled () gets the result of each Promise in the array, whether successful or unsuccessful
const p1 = Promise.resolve(1)
const p2 = Promise.resolve(2)
const p3 = new Promise((resolve, reject) = > {
setTimeout(reject, 1000.'three');
});
Promise.allSettled([p1, p2, p3])
.then(values= > {
console.log(values)
})
/* [ {status: "fulfilled", value: 1}, {status: "fulfilled", value: 2}, {status: "rejected", reason: "three"} ] */
Copy the code
When the browser does not support Promise.allSettled, you can polyfill:
if (!Promise.allSettled) {
const rejectHandler = reason= > ({status: "rejected", reason})
const resolveHandler = value= > ({status: "fulfilled", value})
Promise.allSettled = promises= >
Promise.all(
promises.map((promise) = >
Promise.resolve(promise)
.then(resolveHandler, rejectHandler)
)
// Each promise needs to be wrapped in promise.resolve
// In case of passing a non-promise
);
}
/ / use
const p1 = Promise.resolve(1)
const p2 = Promise.resolve(2)
const p3 = new Promise((resolve, reject) = > {
setTimeout(reject, 1000.'three');
})
const promises = [p1, p2, p3]
Promise.allSettled(promises).then(console.log)
Copy the code
Promise.allsettled () and promise.all () will be settled on the same day
Promise.allSettled()
More suitable for:
- They’re not dependent on each other, and neither of them is
reject
Has no effect on anything else - Expect to know every
promise
Execution result of
Promise.all()
More suitable for:
- Each of them is dependent on the other
reject
Everything else has lost its real value
Handwriting promise.allsettled source code
Unlike promise. all, when a Promise is rejected, we don’t reject it directly. Instead, we record the reject value and the state ‘rejected’;
Similarly, when a promise object is resolved we are not limited to recording the value, but also recording the state ‘fulfilled’.
When all promise objects have been executed (resolved or rejected), we resolve all promise execution results
MyPromise.allSettled = function (promises) {
return new MyPromise((resolve, reject) = > {
promises = Array.isArray(promises) ? promises : []
let len = promises.length
const argslen = len
// If an empty array is passed, return a resolved empty array Promise object
if (len === 0) return resolve([])
// Convert the passed arguments to an array and assign them to the args variable
let args = Array.prototype.slice.call(promises)
// Determine whether all promises have been executed. Resolve when all promises have been executed
const compute = () = > {
if(--len === 0) {
resolve(args)
}
}
function resolvePromise(index, value) {
// Check whether a promise type was passed in
if(value instanceof MyPromise) {
const then = value.then
then.call(value, function(val) {
args[index] = { status: 'fulfilled'.value: val}
compute()
}, function(e) {
args[index] = { status: 'rejected'.reason: e }
compute()
})
} else {
args[index] = { status: 'fulfilled'.value: value}
compute()
}
}
for(let i = 0; i < argslen; i++){
resolvePromise(i, args[i])
}
})
}
Copy the code
conclusion
One failure is all or nothing. Independent of each other, obtain each outcome using promise.allsettled
Three minutes a day, advance one