业务背景:为了对promise有更深刻的理解和认识,手动实现一个promise
按照以下步骤依次实现Promise的手动封装:
1.promise就是一个类,再执行这个类的时候,需要传递一个执行器进去 执行器会立即执行
2.Promise有三种状态,分别为 成功fulfilled 失败 rejected 等待pending
pending–fulfilled
pending–rejected
状态一旦确定不能修改
3.relove和reject函数是用来更改状态的
resolve: fulfilled
reject: rejected
4.then方法内部就是判断状态 如果状态是成功 调用成功回调函数 如果是失败调用失败回调函数 then方法是被定义在原型对象上的
5.then成功回调有个参数 表示成功之后的值 失败回调有个参数 表示失败后的值
6. 同一个promise对象下面的then方法是可以被调用多次的(需要用到while循环)
7. then方法是可以被链式调用的, 后面then方法的回调函数拿到值的是上一个then方法的回调函数的返回值(返回值可能是基本类型 也可能是promise)
判断 x 的值是普通值还是promise对象
如果是普通值 直接调用resolve
如果是promise对象 查看promsie对象返回的结果
再根据promise对象返回的结果 决定调用resolve 还是调用reject
8.then方法链式调用识别promise对象自返回(判断返回的和当前是否一样 出现promise的循环调用 提示错误)
9.捕获错误(执行器的错误,then回调函数的错误)
10.then参数变成可选参数
11.promise.all(解决并发 允许我们按照异步代码调用的顺序得到异步代码执行的结果)
12.promise.resolve()方法是将给定的值转换成promise对象 返回值就是promise对象 会包裹给定的值 如果值是promise对象 直接返回 否则创建promise对象再返回
13.finally方法 无论什么结果都会执行;可以链式调用then;属于实例方法
14.catch方法 调用then方法 第一个参数传undefined 第二个是失败回调
const PENDING = 'pending'; // 等待
const FULFILLED = 'fulfilled'; // 成功
const REJECTED = 'rejected'; // 失败
class myPromise {
constructor(executor){
// 捕获执行器错误
try {
executor(this.resolve, this.reject)
} catch (error) {
this.reject(error)
}
}
status= PENDING //状态
value = undefined // 成功的参数
reason = undefined // 失败的原因
successCallback = [] //成功的回调
failCallback = [] //成功的回调
resolve = value =>{ // 之所以用箭头函数 就是让调用resolve的this指向这个实例对象myPromise
// 判断状态是否是pengding 不是终止更改
if (this.status !== PENDING) return
// 状态更改为成功
this.status = FULFILLED
// 保存成功后的值
this.value = value
// 判断成功回调是否存在 存在 调用
// this.successCallback && this.successCallback(this.value)
// 处理then方法多次调用执行
while(this.successCallback.length) this.successCallback.shift()()
}
reject = reason => {
if (this.status !== PENDING) return
// 状态更改为失败
this.status = REJECTED
// 保存失败的原因
this.reason = reason
// 判断失败回调是否存在 存在 调用
// this.failCallback && this.failCallback(this.value)
while(this.failCallback.length) this.failCallback.shift()()
}
then (successCallback, failCallback) {
// then方法变成可选参数
successCallback = successCallback ? successCallback : value => value
failCallback = failCallback ? failCallback : reason => { throw reason}
// then方法的链式调用 每个then都返回promise
let promise1 = new myPromise ((resolve, reject)=>{
if (this.status == FULFILLED) { // 成功状态调用成功的回调函数
setTimeout(()=>{
try { // 捕获then方法错误
let x = successCallback(this.value) //保存前一个then返回的结果
// 判断 x 的值是普通值还是promise对象
// 如果是普通值 直接调用resolve
// 如果是promise对象 查看promsie对象返回的结果
// 再根据promise对象返回的结果 决定调用resolve 还是调用reject
orPromiseFn(promise1, x, resolve, reject) // 传递给下一个then
} catch (error) {
reject(error)
}
},0)
} else if (this.status == REJECTED) { // 失败状态调用的回失败调函数
setTimeout(()=>{
try {
let x = failCallback(this.reason) //保存前一个then返回的结果
// 判断 x 的值是普通值还是promise对象
// 如果是普通值 直接调用resolve
// 如果是promise对象 查看promsie对象返回的结果
// 再根据promise对象返回的结果 决定调用resolve 还是调用reject
orPromiseFn(promise1, x, resolve, reject) // 传递给下一个then
} catch (error) {
reject(error)
}
},0)
} else { //等待 是异步逻辑
// 需要把成功和失败的回调存起来
this.successCallback.push(()=>{
setTimeout(()=>{
try {
let x = successCallback(this.value) //保存前一个then返回的结果
// 判断 x 的值是普通值还是promise对象
// 如果是普通值 直接调用resolve
// 如果是promise对象 查看promsie对象返回的结果
// 再根据promise对象返回的结果 决定调用resolve 还是调用reject
orPromiseFn(promise1, x, resolve, reject) // 传递给下一个then
} catch (error) {
reject(error)
}
},0)
})
this.failCallback.push(()=>{
setTimeout(()=>{
try {
let x = failCallback(this.reason) //保存前一个then返回的结果
// 判断 x 的值是普通值还是promise对象
// 如果是普通值 直接调用resolve
// 如果是promise对象 查看promsie对象返回的结果
// 再根据promise对象返回的结果 决定调用resolve 还是调用reject
orPromiseFn(promise1, x, resolve, reject) // 传递给下一个then
} catch (error) {
reject(error)
}
},0)
})
}
})
return promise1
}
finally (callback) {
return this.then(val => {
return myPromise.resolve(callback()).then(()=>val)
},reason=>{
return myPromise.resolve(callback()).then(()=>{throw reason})
})
}
catch (failCallback) {
return this.then(undefined, failCallback)
}
static all(array){ //静态方法
let result = []
let index = 0
return new myPromise((resolve, reject)=>{
function addData(key, val) {
result[key] = val
index ++
if(index == array.length){
resolve(result)
}
}
for(let i=0; i<array.length; i++){
let current = array[i]
if(current instanceof myPromise){
// promise对象
current.then(val => addData(i, val), reason=>addData(i, reason))
} else {
// 普通值
addData(i, current)
}
}
})
}
static resolve (cur) {
if(cur instanceof myPromise) return cur
return new myPromise(resolve => resolve(cur))
}
}
function orPromiseFn (promise1, x, resolve, reject) {
if(promise1 === x) {
return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))
}
if(x instanceof myPromise) {
//promise对象 成功走成功 失败走失败
x.then(value=> resolve(value),reason=> reject(reason))
} else {
// 普通值 直接调用resolve
resolve(x)
}
}
module.exports = myPromise
说明:只是初步实现了功能,没有过多兼容,欢迎大佬讨论交流
觉得不错,赏个关注呗😀,不胜感激Thanks♪(・ω・)ノ