原文地址
注:代码格式化有点问题,因为在语雀写作使用了 tab 缩进,所以请移步到原文观看,不想调整代码了……
概述
6 个静态方法的一些注意点罗列如下:
- 除了
resolve
reject
其它静态方法的参数都要求传递一个可迭代对象(iterable),而可迭代对象具有 Symbol.iterator 属性定义生成器(执行生成器生成迭代器),通过判断实参 Symbol.iterator 是否为函数作防御性检测 try...catch
是把未传参数或者传undefined
时 reject 错误信息传递出去- 静态方法都返回 promise,所以基本思路是返回一个 promise 实例,再根据接口的各自用途实现内部逻辑
- iterable 对象中每一项同时执行(当然还是顺序执行,但不必等待其它项的执行结果)
- 由于 iterable 对象中的每一项不必是 promise 实例,那么使用 Promise.resolve 包一下强制生成 promise 实例
- 多条 promise 链,同样位置的回调同属一个微任务队列,链条后面同样位置的回调同属于后面的微任务队列,如下:
Promise.reject(1).catch(r=>console.log(r))
Promise.reject(2).then(r=>console.log(r)).catch(e=>console.log('e',e))
Promise.resolve(3).then(r=>console.log(r)).then(_=>console.log('then'))
// 1
// 3
// e 2
// then
Promise.resolve
快速生成一个 fulfilled promise 对象
Promise._resolve = value => new Promise(resolve => resolve(value))
Promise.reject
快速生成一个 rejected promise 对象
Promise._reject = value => new Promise((_, reject) => reject(value))
Promise.all
iterable 对象只要有一项的状态是 rejected 返回的 promise 状态为 rejected,否则为 fulfilled
Promise._all = array => {
return new Promise((resolve, reject) => {
try{
if (typeof array[Symbol.iterator] !== 'function') return reject(new TypeError(`${typeof array} ${array} is not iterable (cannot read property Symbol(Symbol.iterator))`))
array = [...array[Symbol.iterator]()]
const result = []
let length = array.length
array.forEach((item, i) => Promise.resolve(item)
.then(data => {
result[i] = data
--length === 0 && resolve(result)
}, reject)
)
}catch(e){
reject(e)
}
})
}
Promise.allSettled
返回的 promise 状态都 fulfilled,其中每一项的详情通过传递给成功回调的对象描述,结构为 [{status: 'fulfilled', value: 1}, {status: 'rejected', reason: 'something went wrong']
Promise._allSettled = array => {
return new Promise((resolve, reject) => {
try{
if (typeof array[Symbol.iterator] !== 'function') reject(new TypeError(`${typeof array} ${array} is not iterable (cannot read property Symbol(Symbol.iterator))`))
array = [...array[Symbol.iterator]()]
const result = []
let length = array.length
array.forEach((item, i) => Promise.resolve(item)
.then(value => {
result[i] = {
status: 'fulfilled',
value
}
--length === 0 && resolve(result)
}, e => {
result[i] = {
status: 'rejected',
reason: e
}
--length === 0 && resolve(result)
})
)
}catch(e){
reject(e)
}
})
}
Promise.any
与 Promise.all
相反,只要有一项状态为 fulfilled 返回 promise 状态为 fulfilled,否则为 rejected
Promise._any = array => {
return new Promise((resolve, reject) => {
try{
if (typeof array[Symbol.iterator] !== 'function') reject(new TypeError(`${typeof array} ${array} is not iterable (cannot read property Symbol(Symbol.iterator))`))
array = [...array[Symbol.iterator]()]
const result = []
let length = array.length
array.forEach((item, i) => Promise.resolve(item)
.then(resolve, e => {
--length === 0 && reject(`AggretatedError: All promises were rejected`)
})
)
}catch(e){
reject(e)
}
})
}
Promise.race
竞态,iterable 对象中状态先从 pending 转出的那一项成为返回 promise 的状态,并且把数据传递给成功/失败回调
Promise._race = array => {
return new Promise((resolve, reject) => {
try{
if (typeof array[Symbol.iterator] !== 'function') reject(new TypeError(`${typeof array} ${array} is not iterable (cannot read property Symbol(Symbol.iterator))`))
array = [...array[Symbol.iterator]()]
array.forEach(item => Promise.resolve(item)
.then(resolve, reject)
)
}catch(e){
reject(e)
}
})
}
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!