JS手写Promise(详细过程)

PS:JS手写Promise方法的整理在下一篇文章

手写Promise的API(resolve,reject,then,catch,finally,all)_Eric加油学!的博客-CSDN博客

1、基础版Promise

首先,通过一个简单的Promise例子回顾其使用

const promise = new Promise((resolve, reject) => {
    resolve('ok')
});
promise.then((value) => {
    console.log("promise success:", value);
}, (reason) => {
    console.log("promise fail:", reason);
})

控制台输出 promise success: ok

  • 首先我们在调用 Promise 时,会返回一个 Promise 对象  
  • 构建 Promise 对象时,需要传入一个 executor 函数,Promise 的主要业务流程都在 executor 函数中执行  
  • 如果运行在 excutor 函数中的业务执行成功了,会调用 resolve 函数;如果执行失败了,则调用 reject 函数  
  • Promise 的状态不可逆,同时调用 resolve 函数和 reject 函数,默认会采取第一次调用的结果

所以,我们可以得出一些Promise的基本特征:

  1. promise 有三个状态:pendingfulfilled,rejected 
  2. new promise时, 需要传递一个executor()执行器,执行器立即执行
  3. executor接受两个参数,分别是resolvereject
  4. promise 的默认状态是 pending
  5. promise 有一个value保存成功状态的值
  6. promise 有一个reason保存失败状态的值
  7. promise 只能从pendingrejected, 或者从pendingfulfilled,状态一旦确认,就不会再改变
  8. promise 必须有一个then方法,then 接收两个参数,分别是 promise 成功的回调 onFulfilled, 和 promise 失败的回调 onRejected
  9. 如果调用 then 时,promise 已经成功,则执行onFulfilled,参数是promisevalue
  10. 如果调用 then 时,promise 已经失败,那么执行onRejected, 参数是promisereason
  11. 如果 then 中抛出了异常,那么就会把这个异常作为参数,传递给下一个 then 的失败的回调onRejected

根据以上特征,就可以写一些基础版的Promise了

class Promise {
    // Promise 等待态(初始状态)
    static PENDING = 'pending';
    // Promise 失败态
    static REJECTED = 'rejected';
    // Promise 成功态
    static FULFILLED = 'fulfilled';

    constructor(executor){
        // 初始化 Promise 初始状态
        this.status = Promise.PENDING;
        // 定义 Promise 成功的值
        this.value = undefined
        // 定义 Promise 失败的原因
        this.reason = undefined;
        // 定义 resolve 函数
        const resolve = (value) => {
            if(this.status === Promise.PENDING){
                this.status = Promise.FULFILLED;
                this.value = value
            }
        }
        // 定义 reject 函数
        const reject = (reason) => {
            if(this.status === Promise.PENDING){
                this.status = Promise.REJECTED;
                this.reason = reason
            }
        };
        try {
            executor(resolve, reject);
        } catch (e) {
            reject(e);
        }
        
    }
    then(onFulfilled,onRejected){
        if(this.status === Promise.FULFILLED){
            onFulfilled(this.value)
        }
        if(this.status === Promise.REJECTED){
            onRejected(this.reason)
        }
    }
}

module.exports = Promise;

对其进行测试:

const myPromise = require('./promise')

const promise = new myPromise((resolve, reject) => {
    resolve('ok')
});
promise.then((value) => {
    console.log("promise success:", value);
}, (reason) => {
    console.log("promise fail:", reason);
})

输出: promise success: ok

 至此,一个简单的Promise就手写完毕了。不过目前只是实现了同步操作。如果在executor中有一个异步任务呢?

const promise = new Promise((resolve, reject) => {
    setTimeout(()=>{
        resolve('ok')
    },2000)
});
promise.then((value) => {
    console.log("promise success:", value);
}, (reason) => {
    console.log("promise fail:", reason);
})

对于原生Promise,它的输出肯定是 在2秒后打印  promise success:ok

const myPromise = require('./promise')

const promise = new myPromise((resolve, reject) => {
    setTimeout(()=>{
        resolve('ok')
    },2000)
});
promise.then((value) => {
    console.log("promise success:", value);
}, (reason) => {
    console.log("promise fail:", reason);
})

但对于我们刚才手写的基础版Promise而言,它是没有任何输出的

因为setTimeout是一个异步任务,executor执行到这发现是异步任务,暂时不去处理放入微队列,然后执行then时,promise实例的状态其实还是pending,所以不会执行任何操作。但确实2s后,它们的状态变为了fulfilled,我们可以稍微测试一下

const myPromise = require('./promise')

const promise = new myPromise((resolve, reject) => {
    setTimeout(()=>{
        resolve('ok')
    },2000)
});
promise.then((value) => {
    console.log("promise success:", value);
}, (reason) => {
    console.log("promise fail:", reason);
})
setTimeout(()=>{
    console.log(promise);
},2000)

2s后输出  Promise { status: 'fulfilled', value: 'ok', reason: undefined }

所以,在这个逻辑上,我们能否把成功和失败的回调先存储起来,当executor中的异步任务被执行时,触发resolve或reject再依次调用其回调呢?

class Promise {
    // Promise 等待态(初始状态)
    static PENDING = 'pending';
    // Promise 失败态
    static REJECTED = 'rejected';
    // Promise 成功态
    static FULFILLED = 'fulfilled';

    constructor(executor){
        // 初始化 Promise 初始状态
        this.status = Promise.PENDING;
        // 定义 Promise 成功的值
        this.value = undefined
        // 定义 Promise 失败的原因
        this.reason = undefined;

        // 定义存储 then 方法中成功的回调
        this.onFulfilledCallbacks = [];
        // 定义存储 then 方法中失败的回调
        this.onRejectedCallbacks = [];

        // 定义 resolve 函数
        const resolve = (value) => {
            if(this.status === Promise.PENDING){
                this.status = Promise.FULFILLED;
                this.value = value
                this.onFulfilledCallbacks.forEach(fn => fn())
            }
        }
        // 定义 reject 函数
        const reject = (reason) => {
            if(this.status === Promise.PENDING){
                this.status = Promise.REJECTED;
                this.reason = reason
                this.onRejectedCallbacks.forEach(fn => fn())
            }
        };
        try {
            executor(resolve, reject);
        } catch (e) {
            reject(e);
        }
        
    }
    then(onFulfilled,onRejected){
        if(this.status === Promise.FULFILLED){
            onFulfilled(this.value)
        }
        if(this.status === Promise.REJECTED){
            onRejected(this.reason)
        }
        if(this.status === Promise.PENDING){
            this.onFulfilledCallbacks.push(() => {
                onFulfilled(this.value)
            })
            this.onRejectedCallbacks.push(() => {
                onRejected(this.reason)
            })
        }
    }
}

module.exports = Promise;

我们的思路是:

1、既然执行到then时,由于有异步任务,所以状态仍是 pending,那我们先对其状态进行判断 if(this.status === Promise.PENDING) ,对resolve和reject的回调进行存储

2、定义存储then中resolve和reject的回调,考虑到可能不只会有一个then方法,所以我们应该定义为 数组

3、当 执行到异步任务 时,他们的状态进行变化,我们在相应的resolve和reject函数中对数组里存储的各个回调依次调用

进行测试:

const myPromise = require('./promise')

const promise = new myPromise((resolve, reject) => {
    setTimeout(()=>{
        resolve('ok')
    },2000)
});
promise.then((value) => {
    console.log("promise success:", value);
}, (reason) => {
    console.log("promise fail:", reason);
})

 2s后输出 promise success: ok 


此外,Promise还有一个优势在于其链式调用,它可以让我们使用Promise时,当then函数中,return了一个值,我们可以在下一个then中获取到。例如: promise.then().then()

其实这种写法也等同于

const promise2 = promise.then((value) => {

},(reason) => {

})

promise2.then(......)

所以先对原生的Promise进行试验:

const promise = new Promise((resolve, reject) => {
    setTimeout(()=>{
        resolve('ok')
    },2000)
});
const promise2 = promise.then((value) => {
    console.log("promise success:", value);
}, (reason) => {
    console.log("promise fail:", reason);
})

promise2.then((value)=>{
    console.log("promise2 success:", value);
},(reason)=>{
    console.log("promise2 fail:", reason);
})

2s后输出:

promise success: ok
promise2 success: undefined

因为我们没有写promise中then方法的返回值,而没有写的话,函数的返回值默认是undefined 

const promise = new Promise((resolve, reject) => {
    setTimeout(()=>{
        resolve('ok')
    },2000)
});
const promise2 = promise.then((value) => {
    console.log("promise success:", value);
    return 123
}, (reason) => {
    console.log("promise fail:", reason);
})

promise2.then((value)=>{
    console.log("promise2 success:", value);
},(reason)=>{
    console.log("promise2 fail:", reason);
})

 如果promise的then有返回值,则输出为

promise success: ok
promise2 success: 123

class Promise {
    // Promise 等待态(初始状态)
    static PENDING = 'pending';
    // Promise 失败态
    static REJECTED = 'rejected';
    // Promise 成功态
    static FULFILLED = 'fulfilled';

    constructor(executor){
        // 初始化 Promise 初始状态
        this.status = Promise.PENDING;
        // 定义 Promise 成功的值
        this.value = undefined
        // 定义 Promise 失败的原因
        this.reason = undefined;

        // 定义存储 then 方法中成功的回调
        this.onFulfilledCallbacks = [];
        // 定义存储 then 方法中失败的回调
        this.onRejectedCallbacks = [];

        // 定义 resolve 函数
        const resolve = (value) => {
            if(this.status === Promise.PENDING){
                this.status = Promise.FULFILLED;
                this.value = value
                this.onFulfilledCallbacks.forEach(fn => fn())
            }
        }
        // 定义 reject 函数
        const reject = (reason) => {
            if(this.status === Promise.PENDING){
                this.status = Promise.REJECTED;
                this.reason = reason
                this.onRejectedCallbacks.forEach(fn => fn())
            }
        };
        try {
            executor(resolve, reject);
        } catch (e) {
            reject(e);
        }
        
    }
    then(onFulfilled,onRejected){
        return new Promise((resolve, reject)=>{
            if(this.status === Promise.FULFILLED){
                const x = onFulfilled(this.value)
                resolve(x)
            }
            if(this.status === Promise.REJECTED){
                onRejected(this.reason)
            }
            if(this.status === Promise.PENDING){
                this.onFulfilledCallbacks.push(() => {
                    const x = onFulfilled(this.value)
                    resolve(x);
                })
                this.onRejectedCallbacks.push(() => {
                    onRejected(this.reason)
                })
            }
        })
    }
}

module.exports = Promise;

 所以,只需要在then函数里面,返回一个新的Promise即可,并且获取成功回调函数的返回值,暴露给resolve

测试后:

promise success: ok
promise2 success: 123 

再看原生Promise对于失败的处理,promise状态变为rejected,promise2走的是 成功的回调。

只有promise中抛错或者是返回一个rejected状态的Promise,promise2才会走失败的回调

const promise = new Promise((resolve, reject) => {
    setTimeout(()=>{
        reject('ok')
    },2000)
});
const promise2 = promise.then((value) => {
    console.log("promise success:", value);
    return 123
}, (reason) => {
    console.log("promise fail:", reason);
})

promise2.then((value)=>{
    console.log("promise2 success:", value);
},(reason)=>{
    console.log("promise2 fail:", reason);
})

promise fail: ok
promise2 success: undefined 

如果我们暂时先不管promise里面抛错或者返回rejected的Promise,那其实和成功一样,我们获取回调返回值并暴露给resolve即可。

then(onFulfilled,onRejected){
        return new Promise((resolve, reject)=>{
            if(this.status === Promise.FULFILLED){
                const x = onFulfilled(this.value)
                resolve(x)
            }
            if(this.status === Promise.REJECTED){
                const x = onRejected(this.reason)
                resolve(x)
            }
            if(this.status === Promise.PENDING){
                this.onFulfilledCallbacks.push(() => {
                    const x = onFulfilled(this.value)
                    resolve(x);
                })
                this.onRejectedCallbacks.push(() => {
                    const x = onRejected(this.reason)
                    resolve(x);
                })
            }
        })
    }

 再考虑一步,如果promise里面抛错了,要如何处理,其实就是可以用try catch捕获一下,一旦抛错,直接reject即可

then(onFulfilled,onRejected){
    return new Promise((resolve, reject)=>{
        if(this.status === Promise.FULFILLED){
            try {
                const x = onFulfilled(this.value)
                resolve(x)
            } catch (e) {
                reject(e)
            }
        }
        if(this.status === Promise.REJECTED){
            try {
                const x = onRejected(this.reason)
                resolve(x)
            } catch (e) {
                reject(e)
            }
        }
        if(this.status === Promise.PENDING){
            this.onFulfilledCallbacks.push(() => {
                try {
                    const x = onFulfilled(this.value)
                    resolve(x);
                } catch (e) {
                    reject(e)
                }
            })
            this.onRejectedCallbacks.push(() => {
                try {
                    const x = onRejected(this.reason)
                    resolve(x);
                } catch (e) {
                    reject(e)
                }
            })
        }
    })
}

至此,promise里面抛错和返回普通值 已经处理好了。 那如果promise里面返回new Promise呢


原生Promise的执行效果如下

const promise = new Promise((resolve, reject) => {
    setTimeout(()=>{
        resolve('ok')
    },2000)
});
const promise2 = promise.then((value) => {
    console.log("promise success:", value);
    return new Promise((resolve,reject) => {
        resolve('ok2')
    })
}, (reason) => {
    console.log("promise fail:", reason);
})

promise2.then((value)=>{
    console.log("promise2 success:", value);
},(reason)=>{
    console.log("promise2 fail:", reason);
})

promise success: ok
promise2 success: ok2

而目前我们的myPromise的输出是如下的:

promise success: ok
promise2 success: Promise {
  status: 'fulfilled',
  value: 'ok2',
  reason: undefined,
  onFulfilledCallbacks: [],
  onRejectedCallbacks: []
}

因为我们直接获取了它的返回值记为x,并resolve(x)。所以可以进行一些处理逻辑 


由于这些处理逻辑基本都一样,所以可以提出去,单独写一个函数

const resolvePromise = (promise2, x, resolve, reject) => {
    
}

 这里接收4个参数,分别是 我们要返回的new Promise2,promise返回的promise,要返回的resolve和reject回调

所以可以这么写(其余的几个if判断里的处理也一样)

    then(onFulfilled,onRejected){
        return new Promise((resolve, reject)=>{
            if(this.status === Promise.FULFILLED){
                try {
                    const x = onFulfilled(this.value)
                    resolvePromise(promise2, x, resolve, reject);
                } catch (e) {
                    reject(e)
                }

这里的promise2是哪里来的呢?其实就是外层要return的这个new Promise,所以我们可以先定义,再最后return

then(onFulfilled,onRejected){
        const promise2 = new Promise((resolve, reject)=>{
            if(this.status === Promise.FULFILLED){
                try {
                    const x = onFulfilled(this.value)
                    resolvePromise(promise2, x, resolve, reject);
                } catch (e) {
                    reject(e)
                }
            }
            ......
        }
        return promise2

但使用这个promise2,是在promise2的定义体内部的,咋获取?

可以使用setTimeout,把它变成异步就可以获取到promise2了

    then(onFulfilled,onRejected){
        const promise2 = new Promise((resolve, reject)=>{
            if(this.status === Promise.FULFILLED){
                setTimeout(()=>{
                    try {
                        const x = onFulfilled(this.value)
                        resolvePromise(promise2, x, resolve, reject);
                    } catch (e) {
                        reject(e)
                    }
                },0)

    then(onFulfilled,onRejected){
        const promise2 = new Promise((resolve, reject)=>{
            if(this.status === Promise.FULFILLED){
                setTimeout(()=>{
                    try {
                        const x = onFulfilled(this.value)
                        resolvePromise(promise2, x, resolve, reject);
                    } catch (e) {
                        reject(e)
                    }
                },0)
            }
            if(this.status === Promise.REJECTED){
                setTimeout(()=>{
                    try {
                        const x = onRejected(this.reason)
                        resolvePromise(promise2, x, resolve, reject);
                    } catch (e) {
                        reject(e)
                }},0)
                
            }
            if(this.status === Promise.PENDING){
                this.onFulfilledCallbacks.push(() => {
                    setTimeout(()=>{
                        try {
                            const x = onFulfilled(this.value)
                            resolvePromise(promise2, x, resolve, reject);
                        } catch (e) {
                            reject(e)
                    }},0)
                    
                })
                this.onRejectedCallbacks.push(() => {
                    setTimeout(()=>{
                        try {
                            const x = onRejected(this.reason)
                            resolvePromise(promise2, x, resolve, reject);    
                        } catch (e) {
                            reject(e)
                        }
                    },0)
                   
                })
            }
        })
        return promise2
    }

所以,接下来就只要完成resolvePromise方法即可

const resolvePromise = (promise2, x, resolve, reject) => {
    // 自己等待自己完成的情况, 直接抛错
    if(x === promise2){
        return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))
    }
    if((typeof x === 'object' && x !== null) || typeof x === 'function'){
        try { // 这里防止返回的对象里面,调用then会报错的情况
            const then = x.then;
            if(typeof then === 'function'){ // 如果then是一个函数,那x就是Promise对象
                then.call(x, (y) => {
                    resolve(y)
                },(r) => {
                    reject(r)
                })
            } else { // 普通对象,上面有then属性而已
                resolve(x)
            }
        } catch (e) {
            reject(e)
        }
    }else{
        // 不是对象也不是函数,那就是普通值,直接resolve
        resolve(x)
    }
}

class Promise {
    // Promise 等待态(初始状态)
    static PENDING = 'pending';
    // Promise 失败态
    static REJECTED = 'rejected';
    // Promise 成功态
    static FULFILLED = 'fulfilled';

    constructor(executor){
        // 初始化 Promise 初始状态
        this.status = Promise.PENDING;
        // 定义 Promise 成功的值
        this.value = undefined
        // 定义 Promise 失败的原因
        this.reason = undefined;

        // 定义存储 then 方法中成功的回调
        this.onFulfilledCallbacks = [];
        // 定义存储 then 方法中失败的回调
        this.onRejectedCallbacks = [];

        // 定义 resolve 函数
        const resolve = (value) => {
            if(this.status === Promise.PENDING){
                this.status = Promise.FULFILLED;
                this.value = value
                this.onFulfilledCallbacks.forEach(fn => fn())
            }
        }
        // 定义 reject 函数
        const reject = (reason) => {
            if(this.status === Promise.PENDING){
                this.status = Promise.REJECTED;
                this.reason = reason
                this.onRejectedCallbacks.forEach(fn => fn())
            }
        };
        try {
            executor(resolve, reject);
        } catch (e) {
            reject(e);
        }
        
    }
    then(onFulfilled,onRejected){
        const promise2 = new Promise((resolve, reject)=>{
            if(this.status === Promise.FULFILLED){
                setTimeout(()=>{
                    try {
                        const x = onFulfilled(this.value)
                        resolvePromise(promise2, x, resolve, reject);
                    } catch (e) {
                        reject(e)
                    }
                },0)
            }
            if(this.status === Promise.REJECTED){
                setTimeout(()=>{
                    try {
                        const x = onRejected(this.reason)
                        resolvePromise(promise2, x, resolve, reject);
                    } catch (e) {
                        reject(e)
                }},0)
                
            }
            if(this.status === Promise.PENDING){
                this.onFulfilledCallbacks.push(() => {
                    setTimeout(()=>{
                        try {
                            const x = onFulfilled(this.value)
                            resolvePromise(promise2, x, resolve, reject);
                        } catch (e) {
                            reject(e)
                    }},0)
                    
                })
                this.onRejectedCallbacks.push(() => {
                    setTimeout(()=>{
                        try {
                            const x = onRejected(this.reason)
                            resolvePromise(promise2, x, resolve, reject);    
                        } catch (e) {
                            reject(e)
                        }
                    },0)
                   
                })
            }
        })
        return promise2
    }
}

module.exports = Promise;

这时,进行测试,就正常了

const myPromise = require('./promise')

const promise = new myPromise((resolve, reject) => {
    setTimeout(()=>{
        resolve('ok')
    },2000)
});
const promise2 = promise.then((value) => {
    console.log("promise success:", value);
    return new Promise((resolve,reject) => {
        resolve('ok2')
    })
}, (reason) => {
    console.log("promise fail:", reason);
})

promise2.then((value)=>{
    console.log("promise2 success:", value);
},(reason)=>{
    console.log("promise2 fail:", reason);
})

promise success: ok
promise2 success: ok2

但如果resolve里面继续new Promise呢,目前只做了一层的处理,所以我们还要递归解析

const promise2 = promise.then((value) => {
    console.log("promise success:", value);
    return new Promise((resolve,reject) => {
        resolve(new Promise((resolve,reject)=>{
            resolve('ok2')
        }))
    })
}, (reason) => {
    console.log("promise fail:", reason);
})

 这样就可以处理嵌套的new Promise情况了


还没结束,如果在promise的return中,连续执行回调,它也会连续执行

const Promise = require('./promise')

const promise = new Promise((resolve, reject) => {
    setTimeout(()=>{
        resolve('ok')
    },2000)
});
const promise2 = promise.then((value) => {
    console.log("promise success:", value);
    return {
        then(onFulfilled,onRejected){
            throw new Error(onFulfilled('ok'))
        }
    }
}, (reason) => {
    console.log("promise fail:", reason);
})

promise2.then((value)=>{
    console.log("promise2 success:", value);
},(reason)=>{
    console.log("promise2 fail:", reason);
})

 

这样肯定是不对的,不可能既成功又失败。 所以应该只让它执行一次 

所以可以设置一个变量called,分别在成功和失败的执行中进行控制

const resolvePromise = (promise2, x, resolve, reject) => {
    // 自己等待自己完成的情况, 直接抛错
    if(x === promise2){
        return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))
    }
    if((typeof x === 'object' && x !== null) || typeof x === 'function'){
        let called = false;
        try { // 这里防止返回的对象里面,调用then会报错的情况
            const then = x.then;
            if(typeof then === 'function'){ // 如果then是一个函数,那x就是Promise对象
                then.call(x, (y) => {
                    if(called) return;
                    called = true;
                    resolvePromise(promise2, y, resolve, reject)
                },(r) => {
                    reject(r)
                })
            } else { // 普通对象,上面有then属性而已
                resolve(x)
            }
        } catch (e) {
            if(called) return;
            called = true;
            reject(e)
        }
    }else{
        // 不是对象也不是函数,那就是普通值,直接resolve
        resolve(x)
    }
}

至此,就实现了Promise最为关键的部分: then的链式调用

完整代码如下:

const resolvePromise = (promise2, x, resolve, reject) => {
    // 自己等待自己完成的情况, 直接抛错
    if(x === promise2){
        return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))
    }
    if((typeof x === 'object' && x !== null) || typeof x === 'function'){
        let called = false;
        try { // 这里防止返回的对象里面,调用then会报错的情况
            const then = x.then;
            if(typeof then === 'function'){ // 如果then是一个函数,那x就是Promise对象
                then.call(x, (y) => {
                    if(called) return;
                    called = true;
                    console.log('test');
                    resolvePromise(promise2, y, resolve, reject)
                },(r) => {
                    reject(r)
                })
            } else { // 普通对象,上面有then属性而已
                resolve(x)
            }
        } catch (e) {
            if(called) return;
            called = true;
            console.log('test');
            reject(e)
        }
    }else{
        // 不是对象也不是函数,那就是普通值,直接resolve
        resolve(x)
    }
}

class Promise {
    // Promise 等待态(初始状态)
    static PENDING = 'pending';
    // Promise 失败态
    static REJECTED = 'rejected';
    // Promise 成功态
    static FULFILLED = 'fulfilled';

    constructor(executor){
        // 初始化 Promise 初始状态
        this.status = Promise.PENDING;
        // 定义 Promise 成功的值
        this.value = undefined
        // 定义 Promise 失败的原因
        this.reason = undefined;

        // 定义存储 then 方法中成功的回调
        this.onFulfilledCallbacks = [];
        // 定义存储 then 方法中失败的回调
        this.onRejectedCallbacks = [];

        // 定义 resolve 函数
        const resolve = (value) => {
            if(this.status === Promise.PENDING){
                this.status = Promise.FULFILLED;
                this.value = value
                this.onFulfilledCallbacks.forEach(fn => fn())
            }
        }
        // 定义 reject 函数
        const reject = (reason) => {
            if(this.status === Promise.PENDING){
                this.status = Promise.REJECTED;
                this.reason = reason
                this.onRejectedCallbacks.forEach(fn => fn())
            }
        };
        try {
            executor(resolve, reject);
        } catch (e) {
            reject(e);
        }
        
    }
    then(onFulfilled,onRejected){
        const promise2 = new Promise((resolve, reject)=>{
            if(this.status === Promise.FULFILLED){
                setTimeout(()=>{
                    try {
                        const x = onFulfilled(this.value)
                        resolvePromise(promise2, x, resolve, reject);
                    } catch (e) {
                        reject(e)
                    }
                },0)
            }
            if(this.status === Promise.REJECTED){
                setTimeout(()=>{
                    try {
                        const x = onRejected(this.reason)
                        resolvePromise(promise2, x, resolve, reject);
                    } catch (e) {
                        reject(e)
                }},0)
                
            }
            if(this.status === Promise.PENDING){
                this.onFulfilledCallbacks.push(() => {
                    setTimeout(()=>{
                        try {
                            const x = onFulfilled(this.value)
                            resolvePromise(promise2, x, resolve, reject);
                        } catch (e) {
                            reject(e)
                    }},0)
                    
                })
                this.onRejectedCallbacks.push(() => {
                    setTimeout(()=>{
                        try {
                            const x = onRejected(this.reason)
                            resolvePromise(promise2, x, resolve, reject);    
                        } catch (e) {
                            reject(e)
                        }
                    },0)
                   
                })
            }
        })
        return promise2
    }
}

module.exports = Promise;

剩下的就是Promise的一些其他方法:resolve、reject、catch、finally、all等

手写Promise的API(resolve,reject,then,catch,finally,all)_Eric加油学!的博客-CSDN博客

 如有帮助,三连一下呀

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/4970.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

为什么诚信是项目管理的关键部分?

由于有许多需要指导的活动部件和风险&#xff0c;管理一个新项目可能是一项具有挑战性的工作。在一些对质量有着严格要求的行业&#xff0c;项目结构、设定目标、跟踪状态、风险管理和资源管理等项目管理原则尤为重要&#xff0c;而领导这项工作的是诚信。那么&#xff0c;究竟…

IP 归属用 Ip2region 就够了

文章目录Ip2region 简介是什么特性支持的编程语言案例实操依赖获取IP输入流转化解析IP测试抖音、微博、小红书等各平台相继上线" 网络用户IP地址显示功能"&#xff0c; 境外显示 国家&#xff0c; 境内显示到 省市&#xff0c;且该功能无法关闭&#xff0c;IP地址为强…

【新2023Q2模拟题JAVA】华为OD机试 - 分苹果

最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为od机试,独家整理 已参加机试人员的实战技巧本篇题解:分苹果 题目 AB两个人把苹果…

第16章_变量、流程控制与游标

第16章_变量、流程控制与游标 &#x1f3e0;个人主页&#xff1a;shark-Gao &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是shark-Gao&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f389;目前状况&#xff1a;23届毕业生&#xf…

ClickHouse学习笔记(三):MergeTree 原理解析

文章目录1、简介2、MergeTree 创建方式与存储结构2.1、MergeTree 的创建方式2.2、MergeTree 的存储结构3、MergeTree 数据分区3.1、分区目录的命名规则3.2、分区目录合并过程4、一级索引4.1、索引粒度4.2、索引生成4.3、索引查询5、二级索引6、数据存储7、数据标记8、协同总结8…

BootStrap4:栅格系统

1、container容器 container&#xff1a;固定宽度的容器container-fluid&#xff1a;响应式容器 2、栅格选项 Bootstrap4 总共有五个栅格等级&#xff0c;每个响应式分界点隔出一个等级 Ps&#xff1a;.row上带有margin-left: -15px;margin-right: -15px;属性&#xff0c;你…

【22年蓝桥杯】十三届蓝桥杯真题JavaB组解析+代码(带你复习知识点)(一)

试题 A: 星期计算 【填空题】 答案&#xff1a;7 解析&#xff1a;直接对所给数进行取余&#xff0c;然后直接再加6&#xff08;注意&#xff1a;不能直接让20^226再对7进行取余操作&#xff0c;这是不对的&#xff0c;这个6可以看成已经取余过了。&#xff09; 直接取余的话可…

Linux系统安装部署及配置Grafana

TOC 用于 UI 展示 wget https://dl.grafana.com/oss/release/grafana-8.0.3-1.x86_64.rpm1 安装 grafana 1.1 下载安装 wget https://dl.grafana.com/oss/release/grafana-8.0.3-1.x86_64.rpmsudo yum install grafana-8.0.3-1.x86_64.rpm1.2 启动&状态查看 sudo syst…

PHP初级教程------------------(3)

目录 文件包含 文件包含的作用 文件包含四种形式 文件加载原理 Include和require区别 文件加载路径 文件嵌套包含 函数 函数的基本概念 函数定义语法 函数命名规范 参数详解 形参 实参 默认值 引用传递 函数体 函数返回值 ​作用域 静态变量 可变函数 匿名函数 闭包 伪类型 文件…

作为一个数学专业的学生,我是怎么看待编程的?

1.概况 博主的专业是数学与应用数学&#xff0c;简称应数。虽然后面跟了个应用数学&#xff0c;但是这个专业应该是本科阶段最接近数学的专业了。我认为这个专业使我具有如下的几个优势&#xff1a; 数学的学习使我具有较强的思维能力。编程本质上就是通过写代码的方式来解决…

大数据Flink进阶(八):Apache Flink架构介绍

Apache Flink架构介绍 一、Flink组件栈 在Flink的整个软件架构体系中,同样遵循这分层的架构设计理念,在降低系统耦合度的同时,也为上层用户构建Flink应用提供了丰富且友好的接口。

山东大学机器学习大作业

数据处理与可视化这里是DLRM模型数据集预处理模块&#xff1a;args.ln_emb ln_emb.tolist() m_spa args.arch_sparse_feature_sizeln_emb np.asarray(ln_emb)num_fea ln_emb.size 1 # num sparse num dense featuresm_den_out ln_bot[ln_bot.size - 1]Sparse fea 26, D…

Java设计模式-3、单例模式

单例模式 单例模式属于创建型模式&#xff0c;⼀个单例类在任何情况下都只存在⼀个实例&#xff0c; 构造⽅法必须是私有的、由⾃⼰创建⼀个静态变量存储实例&#xff0c;对外提供⼀ 个静态公有⽅法获取实例。 优点是内存中只有⼀个实例&#xff0c;减少了开销&#xff0c;尤…

代码随想录|day26|回溯算法part03● 39. 组合总和● 40.组合总和II● 131.分割回文串

今天的练习基本就是回溯法组合问题&#xff0c;这一节只要看labuladong即可。 组合问题&#xff1a; 39. 组合总和---------------------形式三&#xff0c;元素无重可复选 链接&#xff1a;代码随想录 一次对&#xff0c;同样在进入下次循环时&#xff0c;注意startindex是从j…

欧莱雅校招负责人张泽宇:拥抱Z世代,探索新玩法

作为校招HR&#xff0c;你在雇主品牌创新实践的路上做过什么尝试&#xff1f; 2020年&#xff0c;欧莱雅正式推出了全新的雇主品牌价值主张 —— 敢为敢超越&#xff0c;就是欧莱雅&#xff08;Freedom to go beyond, thats the beauty of L’ORAL&#xff09;&#xff0c;鼓励…

使用ChatGPT进行AI对话

1.ChatGPT简介 ChatGPT是美国人工智能研究实验室OpenAI新推出的一种人工智能技术驱动的自然语言处理工具&#xff0c;使用了Transformer神经网络架构&#xff0c;也是GPT-3.5架构&#xff0c;这是一种用于处理序列数据的模型&#xff0c;拥有语言理解和文本生成能力&#xff0c…

C/C++ 日期 时间 函数总结

使用C标准库 有四个与时间相关的类型&#xff1a;clock_t、time_t、size_t 和 tm。类型 clock_t、size_t 和 time_t 能够把系统时间和日期表示为某种整数 头文件 #include <time.h> #include <stdio.h> tm 结构: struct tm {int tm_sec; // 秒&#xff0c;…

隐私计算-TEE执行环境

一、TEE 的定义 论述完 TEE 的概念后&#xff0c;接下来进一步解析 TEE 的深层定义。目前对于 TEE 的定义有很多种形式&#xff0c;针对于不同的安全性需求和平台&#xff0c;TEE 的定义也不尽相同&#xff0c;但在所有 TEE 的定义中都会包含两个最关键的点&#xff1a;独立执…

谈谈分布式一致性机制

分布式中一致性是非常重要的&#xff0c;分为弱一致性和强一致性。 现在主流的一致性协议一般都选择的是弱一致性的特殊版本&#xff1a;最终一致性。下面就从分布式系统的基本原则讲起&#xff0c;再整理一些遵循这些原则的协议或者机制&#xff0c;争取通俗易懂。 但是要真…

【通过代理监听UIScrollView的滚动事件 Objective-C语言】

一、输出,当UIScrollView滚动的时候,实时输出当前UIScrollView滚动的位置, 1.用代理实现吧, contentOffset,代表偏移吧,我需要你当UIScrollView滚动的时候,实时输出UIScrollView滚动的位置, 2.第一,我们如何获得UIScrollView滚动的位置呢,contentOffset,是不是就是…