es6手写promise

//手写promise.js
const PENDING = 'PENDING';
const FULFILLEd = 'FULFILLEd';
const REJECTED = 'REJECTED';

const isPromise = (value) => {
    if ((value != null && typeof value === 'object') || typeof value === 'function') {
        if (typeof value.then == 'function') {
            return true
        }
    } else {
        return false
    }
}

function getResolveValue(promiseNext, raw, resolve, reject) {
    if (raw === promiseNext) {
        return reject(new TypeError('不可返回同一个promise对象'))
    }
    let mark;
    if ((typeof raw === 'object' && raw !== null) || typeof raw === 'function') {
        try {
            let then = raw.then;
            if (typeof then === 'function') {
                then.call(raw, function (next) {
                    if (mark) return;
                    mark = true;
                    getResolveValue(promiseNext, next, resolve, reject)
                }, function (error) {
                    if (mark) return;
                    mark = true;
                    reject(error)
                })
            } else {
                resolve(raw)
            }
        } catch (error) {
            if (mark) return;
            reject(error)
        }
    } else {
        resolve(raw)
    }
}

class SetPromise {
    constructor(executor) {
        this.status = PENDING;
        this.value = null;
        this.reason = null;
        this.onSuccessCallback = [];
        this.onRejectCallBack = [];
        try {
            executor(this.resolve.bind(this), this.reject.bind(this))
        } catch (error) {
            this.reject(error).bind(this)
        }
    }
    static resolve(value){
        if (isPromise(value)) {
            return value
        } else {
            return new SetPromise((resolve, _) => {
                resolve(value)
            })
        }
    }
    static reject(reason){
        return new SetPromise((_, reject) => {
            reject(reason)
        })
    }
    static all(arr){
        if (!Array.isArray(arr)) {
            throw new TypeError('请传入一个数组')
        }
        return new SetPromise((resolve, reject) => {
            try {
                let resultArr = []
                const length = arr.length
                for (let i = 0; i < length; i++) {
                    arr[i].then(data => {
                        resultArr.push(data)
                        if (resultArr.length === length) {
                            resolve(resultArr)
                        }
                    }, reject)
                }
            } catch (error) {
                reject(error)
            }
        })
    }
    static race(arr){
        if (!Array.isArray(arr)) {
            throw new TypeError('请传入一个数组')
        }
        return new SetPromise((resolve, reject) => {
            try {
                const length = arr.length
                for (let i = 0; i < length; i++) {
                    arr[i].then(resolve, reject)
                }
            } catch (error) {
                reject(error)
            }
        })
    }
    resolve(value) {
        if (value instanceof SetPromise) {
            return value.then(this.resolve, this.reject)
        }
        if (this.status === PENDING) {
            this.status = FULFILLEd;
            this.value = value;
            this.onSuccessCallback.forEach(func => {
                func(value)
            })
        }
    }
    reject(reason) {
        if (this.status === PENDING) {
            this.status = REJECTED;
            this.reason = reason;
            this.onRejectCallBack.forEach(func => {
                func(reason)
            })
        }
    }
    then(onFulfilled, onRejected) {
        onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : data => data;
        onRejected = typeof onRejected === 'function' ? onRejected : error => { throw (error) };
        let promiseNext;
        if (this.status === FULFILLEd) {
            return promiseNext = new SetPromise((resolve, reject) => {
                setTimeout(() => {
                    try {
                        let result = onFulfilled(this.value)
                        getResolveValue(promiseNext, result, resolve, reject)
                    } catch (error) {
                        reject(error)
                    }
                })
            })
        } else if (this.status === REJECTED) {
            return promiseNext = new SetPromise((resolve, reject) => {
                setTimeout(() => {
                    try {
                        let result = onRejected(this.reason)
                        getResolveValue(promiseNext, result, resolve, reject)
                    } catch (error) {
                        reject(error)
                    }
                })
            })
        } else if (this.status === PENDING) {
            return promiseNext = new SetPromise((resolve, reject) => {
                this.onSuccessCallback.push(value => {
                    try {
                        let result = onFulfilled(value)
                        getResolveValue(promiseNext, result, resolve, reject)
                    } catch (error) {
                        reject(error)
                    }
                })
                this.onRejectCallBack.push(reason => {
                    try {
                        let result = onRejected(reason)
                        getResolveValue(promiseNext, result, resolve, reject)
                    } catch (error) {
                        reject(error)
                    }
                })
            })
        }
    }
    catch(err) {
        return this.then(null, err)
    }
    finally(cb) {
        return this.then((value) => {
            return SetPromise.resolve(cb()).then(() => {
                return value;
            });
        }, (err) => {
            return SetPromise.resolve(cb()).then(() => {
                throw err;
            });
        });
    }
}



const p1 = new SetPromise((resolve, _) => {
    setTimeout(() => {
        resolve('p1')
    }, 1000)
})


const p2 = new SetPromise((resolve, _) => {
    setTimeout(() => {
        resolve('p2')
    }, 1000)
})

p1.then(res => {
    console.log(res);
    return p2;
}).then(res => console.log(res))

SetPromise.all([p1,p2]).then(res=>{console.log(0,res)})

new SetPromise((resolve, reject) => {
    reject('错误')
}).catch(data => console.log(data)).finally(()=>console.log('finally'))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值