Promise-简单实现

前言

之前讲了一些 Promise 的基础知识,这次来捋一捋 Promise 的简单实现吧。

重要点

首先我们要知道 Promise 的几个重要的特性:

① Promise 的参数是一个函数,函数有两个参数,分别为 resolve 和 reject。JS引擎 会自己提供 resolve 和 reject 函数,也就意味着 我们要实现 Promise 的话,这两个函数要我们自己实现。

② Promise 的初始状态是 pending, then 会返回一个新的 Promise。

③ 为什么 Promise 会在 状态改变 之后自动执行 then?

   我的理解是 Promise 内部有两个 回调函数数组, 为什么是两个,因为 一个存 onResolved, 一个存 onRejected。

   如果 Promise的状态是 pending,就把 then 里面的 两个参数(参数的类型是函数) push 进对应的数组,当 Promise 的状态改变时,如果状态为 resolved,就遍历存放 resolve 函数的数组并执行,如果状态为 rejected, 同理。

根据刚才整理的三个的特性,可以知道了一个大致的内部流程,可以编写下面几行代码:

// 参数是一个函数
function myPromise(executor) {

    // 存储 this 
    var self = this;

    // 初始状态
    self.status = 'pending';

    // Promise 的值
    self.data = undefined;

    // 回调函数数组,当 status 为 pending 时,把 then 里的 onResolved 和 onRejected 函数存起来
    self.onResolvedCallback = [];
    self.onRejectedCallback = [];

    // 定义 resolve 函数
    function resolve(value) {

    }

    // 定义 reject 函数
    function reject(reason) {

    }

    // 执行, 加 try-catch 的原因是为了捕获代码错误
    try {
        executor(resolve, reject);
    } catch(err) {
        reject(err);
    }
}

Promise 的 实例 可以链式调用 then,说明 then 方法是定义在 Promise 的原型上的。

myPromise.prototype.then = function(onResolved, onRejected) {
    return new Promise(function(resolve, reject){

    });
}

接下来,我们自己实现Promise内部的 resolve 和 reject 函数。resolve 和 reject 函数,有三个职责:

改变 Promise 的状态。

将 值 传递给 之后的 then。

执行 then 方法里的函数。

代码如下

function myPromise(executor) {

    // ...

    // 定义 resolve 函数
    function resolve(value) {
        if (self.status === 'pending') {
            self.status = 'resolved';
            self.data = value;
            self.onResolvedCallback.forEach(function(fn, index) {
                fn(value);
            });
        }
    }

    // 定义 reject 函数
    function reject(reason) {
        if (self.status === 'pending') {
            self.status = 'rejected';
            self.data = reason;
            self.onRejectedCallback.forEach(function(fn, index) {
                fn(reason);
            });
        }
    }

    // ...
}    

然后,就是实现 then 方法了。then 方法有哪些功能呢?

当 Promise 的状态为 resolved 时,执行 onResolved。

当 Promise 的状态为 rejected 时,执行 onRejected。

当 Promise 的状态为 pending 时,将 then 的 onResolved、onRejected 参数,存入 onResolvedCallback 、onRejectedCallback。

没错就这么简单,所以说它是一个状态机。代码如下:

myPromise.prototype.then = function(onResolved, onRejected) {

    // 保存 this
    var self = this;

    // 定义一个空函数
    // 处理 Promise 值的穿透
    function noop(val) {
        return val;
    }

    // 兼容参数不是函数的情况
    onResolved = typeof onResolved === 'function' ? onResolved : noop;
    onRejected = typeof onRejected === 'function' ? onRejected : noop;

    // 定义返回值
    var promise = undefined;

    // 以下是三个 if,三段逻辑
    if (self.status === 'resolved') {
        promise = new myPromise(function(resolve, reject) {
            try {
                // 我们在 then 的 onResolved函数 里面 return 一个返回值,给下一个 then 使用
                var result = onResolved(self.data);
                resolve(result);
            } catch(err) {
                reject(err);
            }
        });
    }

    if (self.status === 'rejected') {
        promise = new myPromise(function(resolve, reject) {
            try {
                var result = onRejected(self.data);
            } catch(err) {
                reject(err);
            }
        });
    }

    if (self.status === 'pending') {
        promise = new myPromise(function(resolve, reject) {
            // push 进 onResolvedCallback
            self.onResolvedCallback.push(function(value) {
                try {
                    var result = onResolved(value);
            resolve(result); }
catch(err) { reject(err); } }); // push 进 onRejectedCallback self.onRejectedCallback.push(function(reason) { try { var result = onRejected(reason); } catch (err) { reject(err); } }) }); } // 返回 promise return promise; }

全部代码,就在这里了:

// 参数是一个函数
function myPromise(executor) {

    // 存储 this 
    var self = this;

    // 初始状态
    self.status = 'pending';

    // Promise 的值
    self.data = undefined;

    // 回调函数数组,当 status 为 pedding 时,把 then 里的 onResolved 和 onRejected 函数存起来
    self.onResolvedCallback = [];
    self.onRejectedCallback = [];

    // 定义 resolve 函数
    function resolve(value) {
        if (self.status === 'pending') {
            self.status = 'resolved';
            self.data = value;
            self.onResolvedCallback.forEach(function(fn, index) {
                fn(value);
            });
        }
    }

    // 定义 reject 函数
    function reject(reason) {
        if (self.status === 'pending') {
            self.status = 'rejected';
            self.data = reason;
            self.onRejectedCallback.forEach(function(fn, index) {
                fn(reason);
            });
        }
    }

    // 执行, 加 try-catch 的原因是为了捕获代码错误
    try {
        executor(resolve, reject);
    } catch(err) {
        reject(err);
    }
}

myPromise.prototype.then = function(onResolved, onRejected) {

    // 保存 this
    var self = this;

    // 定义一个空函数
    // 处理 Promise 值的穿透
    function noop(val) {
        return val;
    }

    // 兼容参数不是函数的情况
    onResolved = typeof onResolved === 'function' ? onResolved : noop;
    onRejected = typeof onRejected === 'function' ? onRejected : noop;

    // 定义返回值
    var promise = undefined;

    // 以下是三个 if,三段逻辑
    if (self.status === 'resolved') {
        promise = new myPromise(function(resolve, reject) {
            try {
                // 我们在 then 的 onResolved函数 里面 return 一个返回值,给下一个 then 使用
                var result = onResolved(self.data);
                resolve(result);
            } catch(err) {
                reject(err);
            }
        });
    }

    if (self.status === 'rejected') {
        promise = new myPromise(function(resolve, reject) {
            try {
                var result = onRejected(self.data);
            } catch(err) {
                reject(err);
            }
        });
    }

    if (self.status === 'pending') {
        promise = new myPromise(function(resolve, reject) {
            // push 进 onResolvedCallback
            self.onResolvedCallback.push(function(value) {
                try {
                    var result = onResolved(value);
            resolve(result); }
catch(err) { reject(err); } }); // push 进 onRejectedCallback self.onRejectedCallback.push(function(reason) { try { var result = onRejected(reason); } catch (err) { reject(err); } }) }); } // 返回 promise return promise; }

测试一下:

new myPromise((a, b) => a(1)).then(val => val + 1).then(newVal => alert(newVal));
// alert(2);

// 测试值的穿透
new myPromise((resolve, reject) => resolve(3)).then().then().then(val => alert(val));
// alert(3)

new myPromise((resolve, reject) => {
    setTimeout(resolve, 2000, 'ok');
}).then(val => val).then(val => alert(val));
// 2秒后 alert(ok)

总结:

Promise 的 then, 其实就是把 then的 参数 存储到 前一个 Promise 实例的 onResolvedCallback 和 onRejectedCallback 中,等 前一个 Promise resolve 之后调用。

不得不说,Promise的思想,真的很巧妙。

 缺陷:

① 如果 then 返回的是 Promise ,没有处理。

② 不能和其他版本的 Promise 无缝调用。

 如果你想了解更多内容,请移步我的参考链接。作者讲的深入浅出,非常详细。

如有错误,烦请指出。

参考 

史上最易读懂的 Promise/A+ 完全实现

猜你喜欢

转载自www.cnblogs.com/jkCaptain/p/9087981.html