Promise源码解析

 Promise分析:
 1.promise 就是一个类 在执行这个类的时候,需要传递一个执行器进去,执行器会立即执行
 2.promise 中有三种状态 分别为 成功fulfilled 失败rejected 等待pendeng
    pending -> fulfilled
    pending -> rejected
    一旦状态确定就不可更改
 3.resolve和reject函数是用来更改状态的
    resolve: fulfilled
    reject: rejected
 4.then方法内部做的事情就是判断状态 如果状态是成功 调用成功的回调函数 如果状态是失败 调用失败的回调函数
    then方式是被定义在原型对象中的
 5.then成功回调有一个参数 表示成功之后的值 then失败回调有一个参数 表示失败的原因

// promise 原理代码
const PENDING = 'pending'; // 等待
const FULFILLED = 'fulfilled'; // 成功
const REJECTED = 'rejected'; // 失败
class MyPromise {
    constructor(executor) { // 接收执行器
        try {
            executor(this.resolve, this.reject)
        } catch (e) {
            this.reject(e);
        }
    }
    
    status = PENDING; // promise的状态
    value = undefined; // 成功之后的值
    reason = undefined; // 失败之后的值
    successCallback = []; // 成功回调
    failCallback = []; // 失败回调

    // resolve和reject为什么要用箭头函数?
    // 如果直接调用的话,普通函数this指向的是window或者undefined
    // 用箭头函数就可以让this指向当前实例对象
    resolve = value => {
        // 如果状态不是等待 组织程序向下执行
        if (this.status !== PENDING) return
        // 将状态更改为成功
        this.status = FULFILLED;
        // 保存成功之后的值
        this.value = value;
        // 判断成功回调是否存在 如果存在 调用
        //this.successCallback && this.successCallback(this.value)
        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.reason)
        while (this.failCallback.length) this.failCallback.shift()();
    }

    then(successCallback, failCallback) {
        successCallback = successCallback ? successCallback : value => value;
        failCallback = failCallback ? failCallback : reason => {
            throw reason
        }; // then链式调用参数变为可选参数 例:promise.then().then().then((value)=>{console.log(value)}) // value
        let promise2 = new MyPromise((resolve, reject) => {
            // 传递一个执行器 立马执行
            // 判断状态
            if (this.status === FULFILLED) {
                setTimeout(() => { // 将下面的代码变成异步代码
                    try {
                        let x = successCallback(this.value)
                        // 判断 x 的值是普通值还是promise对象
                        // 如果是普通值 直接调用resolve
                        // 如果是promise对象 查看promise对象返回的结果
                        // 再根据promise对象返回的结果 界定调用resolve 还是reject
                        resolvePromise(x, resolve, reject);
                    } catch (e) { // 处理异常状态
                        reject(e)
                    }
                }, 0)
            } else if (this.status === REJECTED) {
                setTimeout(() => { // 将下面的代码变成异步代码
                    try {
                        let x = failCallback(this.reason)
                        resolvePromise(x, resolve, reject);
                    } catch (e) { // 处理异常状态
                        reject(e)
                    }
                }, 0)
            } else {
                // 当前状态是等待
                // 将成功回调和失败回调存储起来 - 多个then方法调用
                this.successCallback.push(() => {
                    setTimeout(() => { // 将下面的代码变成异步代码
                        try {
                            let x = successCallback(this.value);
                            resolvePromise(x, resolve, reject);
                        } catch (e) { // 处理异常状态
                            reject(e)
                        }
                    }, 0)
                });
                this.failCallback.push(() => {
                    setTimeout(() => { // 将下面的代码变成异步代码
                        try {
                            let x = failCallback(this.reason);
                            resolvePromise(x, resolve, reject);
                        } catch (e) { // 处理异常状态
                            reject(e)
                        }
                    }, 0)
                });

            }
        });
        return promise2;
    }

    finally(callback) {
        /**
         - 无论当前最终状态是成功还是失败,finally都会执行
         - 我们可以在finally方法之后调用then方法拿到结果
         - 这个函数是在原型对象上用的
         * **/
        return this.then(value => {
            return MyPromise.resolve(callback()).then(() => value)
        }, reason => {
            return MyPromise.resolve(callback()).then(() => {
                throw reason
            })
        })
    }

    catch(failCallback) {
        /**
         - catch方法是为了捕获promise对象的所有错误回调的
         - 直接调用then方法,然后成功的地方传递undefined,错误的地方传递reason
         - catch方法是作用在原型对象上的方法
         * **/
        return this.then(undefined, failCallback);
    }

    static all(array) {
        /**
         * 分析一下:
         - all方法接收一个数组,数组中可以是普通值也可以是promise对象
         - 数组中值得顺序一定是我们得到的结果的顺序
         - promise返回值也是一个promise对象,可以调用then方法
         - 如果数组中所有值是成功的,那么then里面就是成功回调,如果有一个值是失败的,那么then里面就是失败的
         - 使用all方法是用类直接调用,那么all一定是一个静态方法
         **/
        let result = [];
        let index = 0;
        return new MyPromise((resolve, reject) => {
            function addData(key, value) {
                // 保存每个传入参数执行完毕,并存储返回值
                result[key] = value;
                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(value => addData(i, value), reason => reject(reason))
                } else {
                    // 普通值
                    addData(i, array[i])
                }
            }
        })
    }

    static resolve(value) {
        /**
         resolve方法的作用是将给定的值转换为promise对象 resolve的返回值的promise对象
         如果参数就是一个promise对象,直接返回,如果是一个值,那么需要生成一个promise对象,把值进行返回
         是Promise类的一个静态方法
         * **/
        if (value instanceof MyPromise) return value;
        return new MyPromise(resolve => resolve(value))
    }
}

function resolvePromise(x, resolve, reject) {
    if (x instanceof MyPromise) {
        // promise 对象
        // x.then( value => resolve(value),reason => reject(reason))
        x.then(resolve, reject)  // 简化
    } else {
        // 普通值
        resolve(x)
    }
}

module.exports = MyPromise;

测试案例:

let promise = new MyPromise((resolve,reject)=>{
    // setTimeout(()=>{ // 异步操作
    //     resolve('成功')
    // },2000)
    resolve('成功')
})
let p1 = promise.then(value =>{
    console.log(value)
    return p1
})

// 测试 then方法可以多次调用
// then 方法的链式调用 1.实现链式调用 2.将一个返回值作为第二个then的参数
promise.then(value => {
    console.log(value);
    return p1
},reason => {
    console.log(reason)
}).then(value => {
    console.log(value)
})
// 打印结果-> 成功 成功
function f1() {
    return new MyPromise(function (resolve,reject) {
        setTimeout(function () {
            resolve('f1')
        },2000)
    })
}
function f2() {
    return new MyPromise(function (resolve,reject) {
        setTimeout(function () {
            resolve('f2')
        },0)
    })
}

// - 测试promise.all方法
MyPromise.all(['a','b',f1(),f2(),'c']).then(function (result) {
    console.log(result);
})

// 打印结果-> a b f1 f2 c

// - 测试 promise.finally方法
f2().finally(()=>{
    console.log('finally')
}).then((value => {
    console.log(value)
}), reason =>{
    console.log(reason)
})
// 打印结果-> flnally f2

// 测试 promise.resolve方法
MyPromise.resolve('100').then(value => console.log(value))  // 打印结果-> 100
MyPromise.resolve(f1()).then(value => console.log(value)) // 打印结果-> f1
function f2() {
    return new MyPromise(function (resolve,reject) {
        setTimeout(function () {
            reject('f2---fail');
        },0)
    })
}

// 测试 promise.catch方法
f2().then(value => {console.log(value)})
    .catch(reason => {console.log(reason)})

// 打印结果-> f2---fail

 

  • 5
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Promise源码实现比较复杂,这里我给你一个简化版的Promise源码示例,以帮助你理解其基本原理: ```javascript // Promise构造函数 function Promise(executor) { var self = this; self.value = null; // Promise的值 self.status = 'pending'; // Promise的状态 self.onResolvedCallbacks = []; // 存储成功回调函数的数组 self.onRejectedCallbacks = []; // 存储失败回调函数的数组 function resolve(value) { if (self.status === 'pending') { self.status = 'resolved'; self.value = value; self.onResolvedCallbacks.forEach(function (callback) { callback(value); }); } } function reject(reason) { if (self.status === 'pending') { self.status = 'rejected'; self.value = reason; self.onRejectedCallbacks.forEach(function (callback) { callback(reason); }); } } try { executor(resolve, reject); } catch (e) { reject(e); } } // then方法 Promise.prototype.then = function (onResolved, onRejected) { var self = this; var promise2; onResolved = typeof onResolved === 'function' ? onResolved : function (value) { return value; }; onRejected = typeof onRejected === 'function' ? onRejected : function (reason) { throw reason; }; if (self.status === 'resolved') { return promise2 = new Promise(function (resolve, reject) { try { var x = onResolved(self.value); resolvePromise(promise2, x, resolve, reject); } catch (e) { reject(e); } }); } if (self.status === 'rejected') { return promise2 = new Promise(function (resolve, reject) { try { var x = onRejected(self.value); resolvePromise(promise2, x, resolve, reject); } catch (e) { reject(e); } }); } if (self.status === 'pending') { return promise2 = new Promise(function (resolve, reject) { self.onResolvedCallbacks.push(function (value) { try { var x = onResolved(value); resolvePromise(promise2, x, resolve, reject); } catch (e) { reject(e); } }); self.onRejectedCallbacks.push(function (reason) { try { var x = onRejected(reason); resolvePromise(promise2, x, resolve, reject); } catch (e) { reject(e); } }); }); } }; // 解析Promise的状态 function resolvePromise(promise, x, resolve, reject) { var then; var thenCalledOrThrow = false; if (promise === x) { return reject(new TypeError('Chaining cycle detected for promise!')); } if (x instanceof Promise) { if (x.status === 'pending') { x.then(function (value) { resolvePromise(promise, value, resolve, reject); }, reject); } else { x.then(resolve, reject); } return; } if ((x !== null) && ((typeof x === 'object') || (typeof x === 'function'))) { try { then = x.then; if (typeof then === 'function') { then.call(x, function rs(y) { if (thenCalledOrThrow) return; thenCalledOrThrow = true; return resolvePromise(promise, y, resolve, reject); }, function rj(r) { if (thenCalledOrThrow) return; thenCalledOrThrow = true; return reject(r); }); } else { resolve(x); } } catch (e) { if (thenCalledOrThrow) return; thenCalledOrThrow = true; return reject(e); } } else { resolve(x); } } ``` 这只是一个简化版的Promise源码实现,真正的Promise实现要考虑更多的细节和边界情况。希望这个示例能帮助你更好地理解Promise的工作原理。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值