这段时间在学习Promise,但始终不得要领。为了更好地理解Promise,我决定自己实现一个简易版的Promise,以学习Promise工作原理。该工程名为ToyPromise,仓库地址如下:
https://github.com/pandengyang/toypromise.git
ToyPromise包含了以下属性和方法:
首先,看一下ToyPromise构造函数,代码如下:
function ToyPromise(resolver, name) { this._status = "pending"; this._name = name; this._fullfilled = function dummyFullfilled(value) { return value; }; this._rejected = function dummyRejected(error) { throw error; }; resolver(this._resolve.bind(this), this._reject.bind(this));}
构造函数先进行了一系列的初始化,包括名称、状态、默认的完成/拒绝回调函数,代码如下:
this._status = "pending"; this._name = name; this._fullfilled = function dummyFullfilled(value) { return value; }; this._rejected = function dummyRejected(error) { throw error; };
默认的完成回调函数将完成值重新返回;默认的拒绝回调函数将拒绝原因重新抛出。
初始化后,构造函数立即执行用户传递的resolver函数,并将_resolve和_reject方法传递给resolver。
resolver(this._resolve.bind(this), this._reject.bind(this));
resolver在决议/拒绝该ToyPromise时会调用该ToyPromise的_resolve/_reject方法。代码如下:
var A = new ToyPromise(function resolver(resolve, reject) { var number = Math.random(); if (number <= 0.5) { resolve("a"); } else { reject(new Error("a")); }}, "A");
_resolve方法中的this指向所属ToyPromise,如果直接将this._resolve作为参数传递给resolver,会发生this绑定丢失。this绑定丢失示例如下:
var name = "window";foo = { name: "foo", bar: function bar() { console.log(this.name); }}; foo.bar(); // foovar bar = foo.bar;bar(); // 输出window,而不是foo,说明this丢失了
为了避免this绑定丢失,我们采用硬绑定的方式来传递_resolve和_reject函数。
re