基础逻辑
- 创建 promise 实例
- 创建 resolve、reject 更新状态
- 创建 then 方法,能够在状态变更后执行相应的承诺时事件
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
class MyPromise{
/*
* 创建 promise 实例时立即执行的方法
* 通过构造函数传入一个执行函数,在 new promise((resolve, reject) => {}) 是就能立即执行这个函数
* 将 resolve reject 通过参数传给执行函数,执行函数中使用者实际情况出发 promise 更新状态。
*/
constructor(executor){
executor(this.resolve, this.reject);
}
status = PENDING;
value = '';
reason = '';
successCallbacks = [];
failCallbacks = [];
/*
* 将状态变更为成功
* 1.主要做3件事:1)更新状态为成功,2)保存成功的值,3)执行承诺事件
* 2.因为这个方法是使用者触发的,所以这里使用箭头函数定义,这样this就能指向promise实例
*/
resolve = value => {
if(this.status !== PENDING) return; // 状态一旦变更就固定了
this.status = FULFILLED;
this.value = value;
while (this.successCallbacks.length){
this.successCallbacks.shift()(this.value);
}
}
/*
* 将状态变更为失败
* 1.主要做3件事:1)更新状态为失败,2)保存失败原因,3)执行承诺事件
*/
reject = reason => {
if(this.status !== PENDING) return;
this.status = REJECTED;
this.reason = reason;
while (this.failCallbacks.length){
this.failCallbacks.shift()(this.value);
}
}
/*
* 承诺状态变更后要执的事件
* 1.根据状态,执行相应的成功还是失败回调
* 2.如果当前状态是 pendding,那么就保存成功失败回调,等转态变更后再执行
*/
then(successCallback, failCallback){
if(this.status === FULFILLED){ // 立即未异步执行 resolve
successCallback(this.value);
}else if(this.status === REJECTED){
failCallback(this.reason);
}else if(this.status === PENDING){
this.successCallbacks.push(successCallback);
this.failCallbacks.push(failCallback);
}
}
}
增加链式调用
也就是实现 p.then().then()
这种情况,做法就是 then 方法返回一个新的 promise
- 返回一个新的 promise
- 用上个 promise 回调返回值更新为当前 promise 的 value
- 回调返回是个 promise 处理
then(successCallback, failCallback){
// 参数可选,这样上个 then 参数为空,也会将上个结果保存到当前 promise
successCallback = successCallback ? successCallback : value => value;
failCallback = failCallback ? failCallback: reason => { throw reason };
let p2 = new MyPromise((resolve, reject) => {
if(this.status === FULFILLED){
let result = successCallback(this.value);
resolvePromise(result, resolve, reject);
}else if(this.status === REJECTED){
let result = failCallback(this.reason);
resolvePromise(result, resolve, reject);
}else if(this.status === PENDING){
// 保存成功失败回调需要增加一层,这样就能处理回调返回值
this.successCallbacks.push(() => {
let result = successCallback(this.value);
resolvePromise(result, resolve, reject);
});
this.failCallbacks.push(() => {
let result = failCallback(this.reason);
resolvePromise(result, resolve, reject);
});
}
});
return p2;
}
处理回调是个 promise
function resolvePromise(x, resolve, reject){
if(x instanceof MyPromise){
x.then(resolve, reject);
}else{
resolve(x);
}
}
捕获异常
- 增加一个 catch 方法
- 处理立即执行中的异常和 then 方法回调中的异常(这两都比较容易,直接在原来操作外使用try catch) 处理立即执行中的异常
constructor(executor){
try{
executor(this.resolve, this.reject);
}catch(e){
this.reject(e);
}
}
处理 then 方法回调中的异常
then(successCallback, failCallback){
// 参数可选
successCallback = successCallback ? successCallback : value => value;
// 参数可选
failCallback = failCallback ? failCallback: reason => { throw reason };
let p2 = new MyPromise((resolve, reject) => {
if(this.status === FULFILLED){
try{
let result = successCallback(this.value);
resolvePromise(result, resolve, reject);
}catch(e){
reject(e);
}
}else if(this.status === REJECTED){
try{
let result = failCallback(this.reason);
resolvePromise(result, resolve, reject);
}catch (e) {
reject(e);
}
}else if(this.status === PENDING){
this.successCallbacks.push(() => {
try{
let result = successCallback(this.value);
resolvePromise(result, resolve, reject);
}catch (e) {
reject(e);
}
});
this.failCallbacks.push(() => {
try{
let result = failCallback(this.reason);
resolvePromise(result, resolve, reject);
}catch (e) {
reject(e);
}
});
}
});
return p2;
}
创建 catch 方法(直接调用then方法)
catch(failCallback){
return this.then(undefined, failCallback)
}
添加 Promise.resolve
- 处理 promise 实例,直接返回
- 处理 thenAbled对象(具有then方法的对象)
- 处理其它
static resolve(value){
if(value instanceof MyPromise){
return value;
}else if(Object.prototype.toString.call(value) === '[object Object]'
&& Object.prototype.toString.call(value.then) === '[object Function]'){
return new MyPromise(value.then);
} else {
return new MyPromise(resolve => resolve(value));
}
}
添加 finally 方法
- 在成功和失败后都执行
- 处理 finally 回调返回 promise
finally(callback){
const P = this.constructor;
// callback中如果返回的promise是rejected,返回的promise是rejected
// 如果返回的promise是fulfilled,返回的promise保持原来的
return this.then(
res => P.resolve(callback()).then(() => res, err => err),
err => P.resolve(callback()).then(() => {throw err}, err => err)
)
}
实现 all 方法
static all(arr){
return new MyPromise((resolve, reject) => {
let result = [];
function addResult(key, value){
result[key] = value;
if(result.length === arr.length){
resolve(result);
}
}
arr.forEach((value, index) => {
if(value instanceof MyPromise){
value.then(res => {
addResult(index, res);
}, err => {
reject(err);
})
}else{
addResult(index, value);
}
})
})
}
完整代码
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;
value = '';
reason = '';
successCallbacks = [];
failCallbacks = [];
resolve = value => {
if(value instanceof MyPromise){
value.then(this.resolve, this.reject);
return;
}
if(this.status !== PENDING) return;
this.status = FULFILLED;
this.value = value;
while (this.successCallbacks.length){
this.successCallbacks.shift()();
}
}
reject = reason => {
if(this.status !== PENDING) return;
this.status = REJECTED;
this.reason = reason;
while (this.failCallbacks.length){
this.failCallbacks.shift()();
}
}
then(successCallback, failCallback){
// 参数可选
successCallback = successCallback ? successCallback : value => value;
// 参数可选
failCallback = failCallback ? failCallback: reason => { throw reason };
let p2 = new MyPromise((resolve, reject) => {
if(this.status === FULFILLED){
try{
let result = successCallback(this.value);
resolvePromise(result, resolve, reject);
}catch(e){
reject(e);
}
}else if(this.status === REJECTED){
try{
let result = failCallback(this.reason);
resolvePromise(result, resolve, reject);
}catch (e) {
reject(e);
}
}else if(this.status === PENDING){
this.successCallbacks.push(() => {
try{
let result = successCallback(this.value);
resolvePromise(result, resolve, reject);
}catch (e) {
reject(e);
}
});
this.failCallbacks.push(() => {
try{
let result = failCallback(this.reason);
resolvePromise(result, resolve, reject);
}catch (e) {
reject(e);
}
});
}
});
return p2;
}
catch(failCallback){
return this.then(undefined, failCallback)
}
finally(callback){
const P = this.constructor;
// callback中如果返回的promise是rejected,返回的promise是rejected
// 如果返回的promise是fulfilled,返回的promise保持原来的
return this.then(
res => P.resolve(callback()).then(() => res, err => err),
err => P.resolve(callback()).then(() => {throw err}, err => err)
)
}
static resolve(value){
if(value instanceof MyPromise){
return value;
}else if(Object.prototype.toString.call(value) === '[object Object]'
&& Object.prototype.toString.call(value.then) === '[object Function]'){
return new MyPromise(value.then);
} else {
return new MyPromise(resolve => resolve(value));
}
}
static all(arr){
return new MyPromise((resolve, reject) => {
let result = [];
function addResult(key, value){
result[key] = value;
if(result.length === arr.length){
resolve(result);
}
}
arr.forEach((value, index) => {
if(value instanceof MyPromise){
value.then(res => {
addResult(index, res);
}, err => {
reject(err);
})
}else{
addResult(index, value);
}
})
})
}
}
function resolvePromise(x, resolve, reject){
if(x instanceof MyPromise){
x.then(resolve, reject);
}else{
resolve(x);
}
}