实现一个符合 Promise/A+ 规范的 MyPromise,并实现 resolve、reject、all、race、defer、deferred等静态方法。
MyPromise
-
作用:创建
MyPromise实例。Promise -
MyPromise接收一个回掉函数
executor -
MyPromise状态
-
pending
- 可以转换成 fulfilled 或 rejected
-
fulfilled
- 不可改变成其他状态
-
rejected
- 不可改变成其他状态
-
pending
-
onFulfilledCallbacks和onRejectedCallbacks-
两个数组,数组每一项是一个函数。分别接收
then里面的第一个参数和第二个参数。 -
状态是
pending的回掉函数。
-
两个数组,数组每一项是一个函数。分别接收
-
resolve
-
promise的状态是fulfilled异常是的处理函数 -
接收
value参数-
如果是
promise,执行then。 -
如果不是
promise,把value做为参数传给onFulfilledCallbacks里的每个函数。
-
如果是
-
-
reject
-
promise的状态是rejected异常是的处理函数 -
接收
reason参数,把reason做为参数传给onRejectedCallbacks里的每个函数。
-
-
执行
executor,如果有异常,抛给reject -
因为
Promise是在同步代码执行完成后再执行,所以要把Mypromise的执行方法resolve和reject放在异步队列里
function MyPromise(executor) {
if (typeof executor !== 'function') {
throw new TypeError('Promise resolver ' + executor + ' is not a function');
}
let self = this;
this.status = 'pending';
this.value = undefined;
this.reason = undefined;
this.onFulfilledCallbacks = [];
this.onRejectedCallbacks = [];
function resolve(value) {
if (value instanceof MyPromise) {
return value.then(resolve, reject);
}
if (self.status === 'pending') {
self.value = value;
self.status = 'fulfilled';
self.onFulfilledCallbacks.forEach(item => item(value));
}
}
function reject(reason) {
if (self.status === 'pending') {
self.reason = reason;
self.status = 'rejected';
self.onRejectedCallbacks.forEach(item => item(reason));
}
}
try {
executor(resolve, reject);
} catch (e) {
reject(e);
}
}
MyPromise.prototype.then
-
作用:接收两个函数参数,第一个函数的参数是
resolve传入的参数,第二个参数是reject传入的参数。Promise#then -
onFulfilled-
MyPromise成功时执行的方法 -
resolve的参数会作为value传给onFulfilled
-
-
onRejected-
MyPromise失败时执行的方法 -
reject的参数会作为value传给onRejected
-
-
返回一个
MyPromise实例newPromise,方便链式调用 -
对三种状态分别处理
-
每个状态中创建
newPromise -
fulfilled-
直接执行
onFulfilled,返回值x -
把
newPromise、x以及newPromise里的resolve、reject做为参数传给resolutionPromise - 把 MyPromise 的参数放在异步队列里
-
直接执行
-
rejected-
直接执行
onRejected,返回值x -
把
newPromise、x以及newPromise里的resolve、reject做为参数传给resolutionPromise - 把 MyPromise 的参数放在异步队列里
-
直接执行
-
pending-
状态待定,把
fulfilled和rejected里的异步函数分别加到onFulfilledCallbacks和onRejectedCallbacks的最后一位
-
状态待定,把
-
每个状态中创建
-
resolutionPromise后面细说 -
用
catch捕获异常,执行reject
MyPromise.prototype.then = function (onFulfilled, onRejected) {
let self = this;
typeof onFulfilled !== 'function' && (onFulfilled = function (value) {
return value;
});
typeof onRejected !== 'function' && (onRejected = function (reason) {
throw reason;
});
let newPromise;
/**
* 分别处理实例的三种状态
*/
if (self.status === 'fulfilled') {
newPromise = new MyPromise(function (resolve, reject) {
setTimeout(function () {
try {
let x = onFulfilled(self.value);
resolutionPromise(newPromise, x, resolve, reject);
} catch (e) {
reject(e);
}
});
});
}
if (self.status === 'rejected') {
newPromise = new MyPromise(function (resolve, reject) {
setTimeout(function () {
try {
let x = onRejected(self.reason);
resolutionPromise(newPromise, x, resolve, reject);
} catch (e) {
reject(e);
}
});
});
}
if (self.status === 'pending') {
newPromise = new MyPromise(function (resolve, reject) {
self.onFulfilledCallbacks.push(function (value) {
setTimeout(function () {
try {
let x = onFulfilled(value);
resolutionPromise(newPromise, x, resolve, reject);
} catch (e) {
reject(e);
}
});
});
self.onRejectedCallbacks.push(function (reason) {
setTimeout(function () {
try {
let x = onRejected(reason);
resolutionPromise(newPromise, x, resolve, reject);
} catch (e) {
reject(e);
}
});
});
});
}
return newPromise;
};
MyPromise.prototype.catch
- 作用:捕获异常
-
返回
MyPromise
MyPromise.prototype.catch = function (onRejected) {
return this.then(undefined, onRejected);
};
The Promise Resolution Procedure
-
Promise解析过程,是以一个
promise、一个值x及resolve,reject做为参数的抽象过程 -
promise等于x,reject抛出异常new TypeError('循环引用') -
x如果不是对象(不包括null)或者函数,执行resolve(x) -
获取
x.then赋值给then-
then如果是function-
把
x做为this调用then,第一个参数是resolvePromise,第二个参数是rejectPromise -
resolvePromise和rejectPromise只有第一次调用有效 -
resolvePromise参数为y,执行resolutionPromise(promise, y, resolve, reject) -
rejectPromise参数为r,执行reject(r)
-
把
-
then如果不是function-
执行
resolve(x)
-
执行
-
-
用捕获上一步的异常
-
执行
reject(e) -
如果执行过
resolvePromise或rejectPromise,忽略
-
执行
function resolutionPromise(promise, x, resolve, reject) {
if (promise === x) {
reject(new TypeError('循环引用'));
}
let then, called;
if (x !== null && (typeof x === 'object' || typeof x === 'function')) {
try {
then = x.then;
if (typeof then === 'function') {
then.call(x, function (y) {
if (called)
return;
called = true;
resolutionPromise(promise, y, resolve, reject);
}, function (r) {
if (called)
return;
called = true;
reject(r);
})
} else {
resolve(x);
}
} catch (e) {
if (called)
return;
reject(e);
}
} else {
resolve(x);
}
}
MyPromise 静态方法
MyPromise.all
- 作用:Promise.all
MyPromise.all = function (promises) {
let called = false;
return new MyPromise(function (resolve, reject) {
let newArr = [], count = 0;
for (let i = 0; i < promises.length; i++) {
let item = promises[i];
if (!(item instanceof MyPromise)) {
item = MyPromise.resolve(item);
}
item.then(function (data) {
if (!called) {
newArr[i] = data;
if (i == count) {
resolve(newArr);
count++;
}
}
}, function (e) {
if (!called) {
reject(e);
called = true;
}
});
}
});
};
MyPromise.race
- 作用:Promise.race
MyPromise.race = function (promises) {
return new MyPromise(function (resolve, reject) {
let called = false;
for (let i = 0; i < promises.length; i++) {
let item = promises[i];
if (!(item instanceof MyPromise)) {
item = MyPromise.resolve(item);
}
item.then(function (data) {
if (!called) {
resolve(data);
called = true;
}
}, function (e) {
if (!called) {
reject(e);
called = true;
}
});
}
})
};
MyPromise.resolve
- 作用:Promise.resolve
MyPromise.resolve = function (value) {
if (value instanceof MyPromise) {
return value;
}
return new MyPromise(function (resolve, reject) {
if (typeof value !== null && typeof value === 'object' && typeof value.then === 'function') {
value.then();
} else {
resolve(value);
}
})
};
MyPromise.reject
- 作用:Promise.reject
MyPromise.reject = function (e) {
return new MyPromise(function (resolve, reject) {
reject(e);
})
};
注:本文内容来自互联网,旨在为开发者提供分享、交流的平台。如有涉及文章版权等事宜,请你联系站长进行处理。