Promise对象方法实现 then catch finally

72 阅读1分钟

queueMicrotask创建微任务

const PROMISE_STATUS_FULFILED = "fulfiled";
const PROMISE_STATUS_PENDING = "pending";
const PROMISE_STATUS_REJECTED = "rejected";
class YUIPromise{
    constructor(executor){
        this.statu = PROMISE_STATUS_PENDING;
        this.onfulfiledcallback = [];
        this.onrejectedcallback = [];
        this.value = undefined;
        this.reason = undefined;
        const resolve = (value) =>{
            this.value = value;
            queueMicrotask(()=>{
                if(this.statu === PROMISE_STATUS_PENDING){
                    this.statu = PROMISE_STATUS_FULFILED;
                    this.onfulfiledcallback.forEach(e=>{
                        e();
                    })
                }
            })
        }
        const reject = (reason) =>{
            this.reason = reason;
            queueMicrotask(()=>{
                if(this.statu === PROMISE_STATUS_PENDING){
                    this.statu = PROMISE_STATUS_REJECTED;
                    this.onrejectedcallback.forEach(e=>{
                        e();
                    })
                }
            })
        }
        executor(resolve,reject)
    }
    then(onfulfiled,onrejected){
        onrejected = onrejected || (err=>{throw err})
        return new YUIPromise((resolve,reject)=>{
            if(this.statu === PROMISE_STATUS_FULFILED){
                try {
                    const value = onfulfiled(this.value)
                    resolve(value)
                } catch (error) {
                    reject(error)
                }
            }
            if(this.statu === PROMISE_STATUS_REJECTED){
                try {
                    const reason = onrejected(this.reason)
                    resolve(reason)
                } catch (error) {
                    reject(error)
                }
            }
            if(this.statu === PROMISE_STATUS_PENDING){
                this.onfulfiledcallback.push(()=>{
                    try {
                        const value = onfulfiled(this.value)
                        resolve(value)
                    } catch (error) {
                        reject(error)
                    }
                });
                this.onrejectedcallback.push(()=>{
                    try {
                        const reason = onrejected(this.reason)
                        resolve(reason)
                    } catch (error) {
                        reject(error)
                    }
                });
            }
        })
    }
    catch(onrejected){
        return this.then(undefined,onrejected)
    }
    finally(onfinally){
        this.then(onfinally)
    }
}

let yui = new YUIPromise((resolve,reject)=>{
    reject('yui')
    // resolve('cc')
})
yui.then(res=>{
    console.log('res'+res)
}).finally(()=>{
    console.log('finally')
})