resolve方法: Promise.resolve的用法相当于new Promise,并且执行resolve操作。
比如:
// 类方法Promise.resolve
const promise = Promise.resolve({ name: "why" })
// 相当于
const promise2 = new Promise((resolve, reject) => {
resolve({ name: "why" })
})
手写实现resolve方法:
static resolve(value) { return new Promise((resolve) => resolve(value)) }
reject方法类似于resolve方法,只是会将Promise对象的状态设置为reject状态。 Promise.reject的用法相当于new Promise,只是会调用reject。 Promise.reject传入的参数无论是什么形态,都会直接作为reject状态的参数传递到catch的。
比如:
const promise = Promise.reject("rejected message")
// 相当于
const promise2 = new Promsie((resolve, reject) => {
reject("rejected message")
})
手写实现reject方法:
static reject(reason) { return new Promise((resolve, reject) => reject(reason)) }
all方法的作用是将多个Promise包裹在一起形成一个新的Promise。新的Promise状态由包裹的所有Promise共同决定:当所有的Promise状态变成fulfilled状态时,新的Promise状态为fulfilled,并且会将所有Promise的返回值组成一个数组;当有一个Promise状态为reject时,新的Promise状态为reject,并且会将第一个reject的返回值作为参数;
比如:
// 创建多个Promise
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(11111)
}, 1000);
})
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
reject(22222)
}, 2000);
})
const p3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(33333)
}, 3000);
})
// 需求: 所有的Promise都变成fulfilled时, 再拿到结果
// 意外: 在拿到所有结果之前, 有一个promise变成了rejected, 那么整个promise是rejected
// "aaaa"相当于Promise.resolve("aaaa")
Promise.all([p2, p1, p3, "aaaa"]).then(res => {
console.log(res)
}).catch(err => {
console.log("err:", err) // err: 22222
})
手写all方法:
static all(promises) {
// 问题关键: 什么时候要执行resolve, 什么时候要执行reject
return new Promise((resolve, reject) => {
const values = []
promises.forEach(promise => {
promise.then(res => {
values.push(res)
// 如果所有的Promise都正确执行了
if (values.length === promises.length) {
resolve(values)
}
}, err => {
// 否则只要有一个执行错误就reject
reject(err)
})
})
})
}
allSettled方法:在所有的Promise都有结果(settled),无论是fulfilled,还是reject时,才会有最终的状态,并且这个Promise的结果一定是fulfilled的。该方法解决了all方法的缺陷:当有其中一个Promise变成reject状态时,新Promise就会立即变成对应的reject状态。那么对于resolved的,以及依然处于pending状态的Promise,我们是获取不到对应的结果的。
比如:
// 创建多个Promise
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(11111)
}, 1000);
})
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
reject(22222)
}, 2000);
})
const p3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(33333)
}, 3000);
})
// allSettled
Promise.allSettled([p1, p2, p3]).then(res => {
console.log("res:",res)
}).catch(err => {
console.log("err:",err)
})
// 输出
// res: [{
// status: 'fulfilled',
// value: 11111
// },
// {
// status: 'rejected',
// reason: 22222
// },
// {
// status: 'fulfilled',
// value: 33333
// }
// ]
手写allSettled方法:
static allSettled(promises) {
return new Promise((resolve) => {
const results = []
promises.forEach(promise => {
promise.then(res => {
results.push({ status: PROMISE_STATUS_FULFILLED, value: res})
if (results.length === promises.length) {
resolve(results)
}
}, err => {
results.push({ status: PROMISE_STATUS_REJECTED, value: err})
if (results.length === promises.length) {
resolve(results)
}
})
})
})
}
race方法:如果有一个Promise有了结果,我们就希望决定最终新Promise的状态,那么可以使用race方法。多个Promise相互竞争,谁先有结果,那么就使用谁的结果。
比如:
// 创建多个Promise
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(11111)
}, 3000);
})
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
reject(22222)
}, 500);
})
const p3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(33333)
}, 1000);
})
// race: 竞技/竞赛
// 只要有一个Promise变成fulfilled/rejected状态, 那么就结束
Promise.race([p1, p2, p3]).then(res => {
console.log("res:", res)
}).catch(err => {
console.log("err:", err)
})
手写race方法:
static race(promises) {
return new Promise((resolve, reject) => {
promises.forEach(promise => {
// promise.then(res => {
// resolve(res)
// }, err => {
// reject(err)
// })
promise.then(resolve, reject)
})
})
}
any方法:any方法会等到一个fulfilled状态,才会决定新Promise的状态,如果所有的Promise都是reject的,那么也会等到所有的Promise都变成rejected状态,会报一个AggregateError的错误。
比如:
// 创建多个Promise
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
// resolve(11111)
reject(1111)
}, 1000);
})
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
reject(22222)
}, 500);
})
const p3 = new Promise((resolve, reject) => {
setTimeout(() => {
// resolve(33333)
reject(3333)
}, 3000);
})
// any方法
Promise.any([p1, p2, p3]).then(res => {
console.log("res:", res)
}).catch(err => {
console.log("err:", err.errors) // err:[1111,22222,3333]
})
手写any方法:
static any(promises) {
// resolve必须等到有一个成功的结果
// reject所有的都失败才执行reject
const reasons = []
return new Promise((resolve, reject) => {
promises.forEach(promise => {
promise.then(resolve, err => {
reasons.push(err)
if (reasons.length === promises.length) {
reject(new AggregateError(reasons))
}
})
})
})
}