持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第1天,点击查看活动详情
Promise使用
new Promise(executor) 实例promise对象的时候传进去了一个执行函数executor。executor 两个参数分别是resolve 和reject,resolve用来将PENDING 改为FULFILLED 的, reject 是将PENDING 改为REJECTED
resolve参数值就是promise的返回值。
then方法的逻辑就是当resolve没执行的时候,也就是状态没变,还是PENDING的时then方法实际做的是successCallback 和failCallback回调的收集,只有状态不为PENDING才会根据状态执行对应的回调successCallback 和failCallback
const value = new Promise((resolve, reject) => {
// setTimeout 就相当于耗时的接口请求
setTimeout(() => {resolve('23')}, 0)
})
value.then(successCallback, failCallback)
const successCallback = (res) => {
console.log('成功的回调')
}
const failCallback = (err) => {
console.log('失败的回调')
}
实际上面的拆分就是我们平时接口请求的如下代码
new Promise((resolve, reject) => {
// setTimeout 就相当于耗时的接口请求
setTimeout(() => {resolve('23')}, 0)
}).then((res) => {
console.log('成功的回调')
}, (err) => {
console.log('失败的回调')
})
Promise.resolve(value)的实现
该方法实际上是快速创建Promise对象,实际返回的就是
new Promise(value)将value值传递给then方法
- 源码实现
Promise.resolve = function (value) {
if (value instanceof Promise) return value
return new Promise(resolve => resolve(value))
}
Promise 高频知识点之all,any,race,allSettled的实现
Promise.all方法的实现
- 使用方法
传一个promise数组进去,全部成功才会走到then回调中, 否则都会到catche方法
Promise.all([p1,p2,p3]).then((res => {
console.log(res)
})).catch((err) => {
console.log(err)
})
- 源码实现
由于传进来的
promiseArray都是可能耗时操作。只有p1,p2,p3执行完了,他们对应的then方法才会执行,then方法里面判断数组和传进来长度一致证明全部执行完了,调最终的resolve,all方法的then的成功回调successCallback才会执行另外只要有一个失败,直接调用了最外层的reject方法,all方法执行结束
Promise.all = function (promiseArray) {
let array = []
return new Promise((resolve, reject) => {
promiseArray.forEach((value, index) => {
// p1,p2,p3 三个promise都会有对应的 Promise.resolve(p) 就相当于传值操作。等到p1,p2, p3 执行完了后才会走对应的then里面的成功回调successCallback
Promise.resolve(value).then((result) => {
array[index] = result
if (array.length === promiseArray.length) {
resolve(array)
}
}, reject)
})
})
}
Promise.race 的实现
race 赛跑, 任意一个promise状态结束就返回,成功或者失败
- 使用
Promise.race([p1,p2,p3]).then(console.log).catch(console.log)
- 实现
Promise.race = function (promiseArray) {
return new Promise(function (resolve, reject) {
promiseArray.forEach(item => Promise.resolve(item).then(resolve,reject))
})
}
Promise.any 的实现
只有一个成功就成功,所有失败才失败. 就是promise.all的resole和reject逻辑互换
Promise.allSettled
相当于all和any 的结合,所有的都走完了才会回调,也就是允许中间可能有失败
- 源码
Promise.MyAllSettled = function (promises) {
let arr = [],
count = 0
return new Promise((resolve, reject) => {
promises.forEach((item, i) => {
Promise.resolve(item).then(res => {
arr[i] = { status: 'fulfilled', val: res }
count += 1
if (count === promises.length) resolve(arr)
}, (err) => {
arr[i] = { status: 'rejected', val: err }
count += 1
if (count === promises.length) resolve(arr)
})
})
})
}