接上篇 符合promiseA+的抄袭 的实现,promise 还有一些在规范之外的语法糖实现
catch finally resolve reject race all
实现代码
catch
MyPromise.prototype.catch = function (onRejected) {
return this.then(null, onRejected)
}
测试代码
new MyPromise((resolve, reject) => {
reject('err')
}).catch((reason) => {
console.log(reason) // err
return 'data'
}).then((value) => {
console.log(value) // data
})
resolve
MyPromise.resolve = (data) => {
// 如果data是个promise会直接返回
if (data instanceof MyPromise) {
return data
} else {
return new MyPromise(resolve => {
resolve(data)
})
}
}
测试代码
MyPromise.resolve(2).then((data) => {
console.log(data) // 2
})
MyPromise.resolve(
new MyPromise((resolve, reject) => {
reject(5)
})
).catch((data) => {
console.log(data) // 5
})
reject
// 和Promise.resolve不同,会直接reject
MyPromise.reject = (reason) => {
return new MyPromise((resolve, reject) => {
reject(reason)
})
}
测试代码
MyPromise.reject(2).catch((reason) => {
console.log(reason) // 2
})
finally
MyPromise.prototype.finally = function (callback) {
return this.then((value) => {
// callback没有参数、
// 如果callback返回的是promise,则会等待promise执行
return MyPromise.resolve(callback()).then(() => {
// finally会保持promise状态和值
return value
})
}, (reason) => {
return MyPromise.resolve(callback()).then(() => {
// finally会保持promise状态和值
throw reason
})
})
}
测试代码
MyPromise.resolve(2).finally((value) => {
console.log(value) // undefined
}).then((value) => {
console.log(value) // 2
})
MyPromise.reject(2).finally((reason) => {
console.log(reason) // undefined
}).catch((reason) => {
console.log(reason) // 2
})
MyPromise.resolve(2).finally((value) => {
return new MyPromise((resolve) => {
setTimeout(() => {
resolve(100)
}, 1000)
})
}).then((value) => {
console.log(value) // 100
})
all
MyPromise.all = (paramList) => {
const len = paramList.length
const result = []
let count = 0
return new MyPromise((resolve, reject) => {
// 参数长度为0直接resolve
if (len === 0) resolve(result)
paramList.forEach((param, index) => {
// 如果数组元素不是promise也会包装成promise
MyPromise.resolve(param).then((value) => {
count++
result[index] = value
if (count === len) {
resolve(result)
}
}, (reason) => {
reject(reason)
})
})
})
}
测试代码
const p1 = new MyPromise((resolve) => {
setTimeout(() => {
resolve(3)
}, 2000)
})
const p2 = new MyPromise((resolve) => {
setTimeout(() => {
resolve(4)
}, 1000)
})
const p3 = new MyPromise((resolve, reject) => {
setTimeout(() => {
reject(5)
}, 1000)
})
MyPromise.all([
1, 2, p1, p2
]).then((value) => {
console.log(value) // [1, 2, 3, 4]
})
MyPromise.all([
1, 2, p1, p2, p3
]).catch((reason) => {
console.log(reason) // 5
})
MyPromise.all([]).then((value) => {
console.log(value) // []
})
race
MyPromise.race = (paramList) => {
return new MyPromise((resolve, reject) => {
// 空数组则保持等待状态
if (paramList.length === 0) return
paramList.forEach((param) => {
Promise.resolve(param).then((value) => {
resolve(value)
}, (reason) => {
reject(reason)
})
})
})
}
测试代码
const p1 = new MyPromise((resolve) => {
setTimeout(() => {
resolve(1)
}, 1000)
})
const p2 = new MyPromise((resolve) => {
setTimeout(() => {
resolve(2)
}, 2000)
})
const p3 = new MyPromise((resolve, reject) => {
setTimeout(() => {
reject(3)
}, 500)
})
MyPromise.race([]).then(value => {
console.log(value)
}, reason => {
console.log(reason)
})
MyPromise.race([1, 2]).then(value => {
console.log(value) // 1
}, reason => {
console.log(reason)
})
MyPromise.race([p1, 4]).then(value => {
console.log(value) // 4
}, reason => {
console.log(reason)
})
MyPromise.race([p1, p2]).then(value => {
console.log(value) // 1
}, reason => {
console.log(reason)
})
MyPromise.race([p1, p3]).then(value => {
console.log(value)
}, reason => {
console.log(reason) // 3
})
参考
欢迎到前端学习打卡群一起学习~516913974