手动实现promise 及 常用方法


const PENDING = 'pending',
    SUCCESS = 'success',
    FAILED = 'failed';
const resolvePromise = (newPromise, x, res, rej) => {
    if (newPromise === x) rej(new TypeError('Chaining cycle detected for promise #<Promise>'));
    let called;
    if (typeof x === 'function' || (typeof x === 'object' && x !== null)) {
        try {
            let then = x.then;
            if (typeof then === 'function') {
                then.call(x,
                    y => {
                        if (called) return;
                        called = true;
                        resolvePromise(newPromise, y, res, rej)
                    },
                    e => {
                        if (called) return;
                        called = true;
                        rej(e)
                    }
                );
            } else {
                res(x)
            }
        } catch (error) {
            if (called) return;
            called = true;
            rej(x)
        }
    } else {
        res(x)
    }
}
function isPromise(value) {
    if (typeof value === 'function' || (typeof value === 'object' && value !== null)) {
        if (typeof value.then === 'function') {
            return true;
        }
    }
    return false;
}
class Promise {
    constructor(executor) {
        this.status = PENDING;
        this.value = null;
        this.err = null;
        this.onFCB = [];
        this.onRCB = [];
        let resolve = value => {
            if (this.status === PENDING) {
                this.status = SUCCESS;
                this.value = value;
                this.onFCB.forEach(fn => fn(this.value));
            }
        }
        let reject = err => {
            if (this.status === PENDING) {
                this.status = FAILED;
                this.err = err;
                this.onRCB.forEach(fn => fn(this.err));
            }
        }
        try {
            executor(resolve, reject);
        } catch (error) {
            reject(error)
        }
    }
    then(onF, onR) {
        onF = typeof onF === 'function' ? onF : val => val;
        onR = typeof onR === 'function' ? onR : err => {
            throw err; Î
        }
        let newPromise;
        newPromise = new Promise((res, rej) => {
            switch (this.status) {
                case SUCCESS:
                    setTimeout(() => {
                        try {
                            let x = onF(this.value);
                            resolvePromise(newPromise, x, res, rej);
                        } catch (error) {
                            rej(error)
                        }
                    })
                    return;
                case FAILED:
                    setTimeout(() => {
                        try {
                            let x = onR(this.err);
                            resolvePromise(newPromise, x, res, rej);
                        } catch (error) {
                            rej(error)
                        }
                    })
                    return;
                case PENDING:
                    this.onFCB.push(() => {
                        setTimeout(() => {
                            try {
                                let x = onF(this.value);
                                resolvePromise(newPromise, x, res, rej);
                            } catch (error) {
                                rej(error)
                            }
                        })
                    })
                    this.onRCB.push(() => {
                        setTimeout(() => {
                            try {
                                let x = onR(this.err);
                                resolvePromise(newPromise, x, res, rej);
                            } catch (error) {
                                rej(error)
                            }
                        })
                    })
                    return;
                default:
                    return;
            }
        })
        return newPromise;
    }






}

// 实现promise catch finally all race resolve reject
// catch then语法糖
Promise.prototype.catch = function (cb) {
    return this.then(null, cb);
}
// resolve 少包一层 直接返回一个promise实例并执行成功传入value
Promise.resolve = function (value) {
    return new Promise((resolve, reject) => {
        resolve(value);
    })
}
// reject 少包一层 直接返回一个promise实例并执行成功传入value
Promise.reject = function (e) {
    return new Promise((resolve, reject) => {
        reject(e);
    })
}
// finally 无论如何都执行
Promise.prototype.finally = function (cb) {
    return this.then(
        value => { // 无论正确还是失败都走这个回调,为了保证cb执行后在进行下一步,利用promise的res方法有等待异步执行的特点
            return Promise.resolve(cb()).then(() => value);
        },
        e => {
            return Promise.resolve(cb()).then(() => { throw e }); // koa 原理
        }
    )
}

// 多个promise按顺序获取对应的值
Promise.all = function () {
    return new Promise((resolve, reject) => { //首先建立一个promise

        let arr = []; // arr[3] = 2  arr.length = 4
        let i = 0;

        let processData = (key, value) => {
            arr[key] = value; // after函数
            if (++i === values.length) { // 直到全部异步都执行完毕在去调用res方法返回对应数据
                resolve(arr);
            }
        }
        // 循环执行每一个异步调用
        for (let i = 0; i < values.length; i++) {
            let current = values[i];
            if (isPromise(current)) { // 如果是promise那么就执行then拿到结果
                current.then(y => {
                    processData(i, y);
                }, reject);
            } else {
                processData(i, current); // 如果不是直接把值传出去
            }
        }
    })
}
// 多个promise 看那个执行速度最快不管成功失败都返回最快的那个执行结果
Promise.race = function (values) {
    return new Promise((resolve, reject) => {
        // 循环所有值
        for (let i = 0; i < values.length; i++) {
            let current = values[i];
            if (isPromise(current)) { // 是promise执行这个promise
                current.then(resolve, reject);
            } else { // 不是的话直接返回这个值
                resolve(current);
            }
        }
    })
}Ï
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值