Promise是处理异步编码的一个解决方案,在Promise出现以前,异步代码的编写都是通过回调函数来处理的,回调函数本身没有任何问题,只是当多次异步回调有逻辑关系时就会变得复杂:
const fs = require('fs');
fs.readFile('1.doc', (err,res) => {
fs.readFile('2.doc', (err,res) => {
fs.readFile('3.doc', (err,res) => {
// 可能还有后续代码...
});
});
});
不过Promise的横空出世就有效的解决了这一问题,也就是回调地狱问题;
而手写Promise也是最近几年面试很容易考到的问题,下面收集了简易版的Promise和合乎Promises/A+规范的Promise,仅供参考!
constructor(fn) {
// 定义Promise的三种状态
this.statusObj = {
PENDING: 'PENDING',
RESOLVED: 'RESOLVED',
REJECTED: 'REJECTED'
}
this.value = null;// 定义传递给then的value
this.status = this.statusObj.PENDING; // 设置当前Promise的状态
this.resolvedCallBacks = []; // 定义Promise成功状态的回调函数集合
this.rejectedCallBacks = []; // 定义Promise失败状态的回调函数集合
MyPromise.that = this; // 为静态方法定义其内部可以使用的指向实例的that
try {
// 执行new Promise() 内传入的方法
fn(MyPromise.resolve, MyPromise.reject);
} catch (error) {
MyPromise.reject(this.value);
}
}
/**
* 静态resolve方法,MyPromise实例不可访问;
* 支持类MyPromise访问,例:MyPromise.resolve('success').then(e=>e)
* @param value
*/
static resolve(value) {
const that = MyPromise.that; // 由于静态方法内的this访问的是类还不是实例,所以使用这种办法访问对象实例
const f = that instanceof MyPromise; // 确认是否是MyPromise实例访问resolve
// MyPromise 实例访问resolve,如果访问成功 状态改变、值改变
if (f && that.status === that.statusObj.PENDING) {
that.status = that.statusObj.RESOLVED;
that.value = value;
that.resolvedCallBacks.map(cb => that.value = cb(that.value));
}
// MyPromise 类访问resolve
if (!f) {
const obj = new MyPromise();
return Object.assign(obj, {
status: obj.statusObj.RESOLVED,
value
})
}
}
那么resolve方法就和resolve方法差不多
/**
* 静态resolve方法
* @param value
*/
static reject(value) {
const that = MyPromise.that;
const f = that instanceof MyPromise;
if (f && that.status === that.statusObj.REJECTED) {
that.status = that.statusObj.REJECTED;
that.value = value;
that.rejectedCallBacks.map(cb => that.value = cb(that.value));
}
if (!f) {
const obj = new MyPromise();
return Object.assign(obj, {
status: that.statusObj.REJECTED,
value
})
}
}
最后是then方法
/**
* MyPromise 原型上的then方法
* @param onFulfilled
* @param onRejected
*/
then(onFulfilled, onRejected) {
const { PENDING, RESOLVED, REJECTED } = this.statusObj;
const f = typeof onFulfilled == 'function' ? onFulfilled : c => c
const r = typeof onRejected == 'function' ? onRejected : c => { throw c };
switch (this.status) {
case PENDING: // PENDING 状态下 向下回调函数结合添加callback
this.resolvedCallBacks.push(f);
this.rejectedCallBacks.push(r);
break;
case RESOLVED:
this.value = f(this.value); // 将回调函数的返回值赋值给实例的 value ,满足链式调用then方法时传递value
break;
case REJECTED:
this.value = r(this.value); // 将回调函数的返回值赋值给实例的 value ,满足链式调用then方法时传递value
break;
default:
break;
}
// 满足链式调用then,返回MyPromise实例对象
return this
}
至此呢,我们自定的MyPromise方法就写完了 ,接下里就是测试环节
// new 一个Promise进行测试
MyPromise.resolve('success').then((e) => {
console.log(e);
return e + 1;
}).then((res) => {
console.log(res);
});
new MyPromise(resolve => {
setTimeout(() => {
resolve(1)
}, 2000);
})
.then((res2) => {
console.log(res2);
return 2;
}).then((res3) => {
console.log(res3);
})
class MyPromise {
constructor(fn) {
// 定义Promise的三种状态
this.statusObj = {
PENDING: 'PENDING',
RESOLVED: 'RESOLVED',
REJECTED: 'REJECTED'
}
this.value = null;// 定义传递给then的value
this.status = this.statusObj.PENDING; // 设置当前Promise的状态
this.resolvedCallBacks = []; // 定义Promise成功状态的回调函数集合
this.rejectedCallBacks = []; // 定义Promise失败状态的回调函数集合
MyPromise.that = this; // 为静态方法定义其内部可以使用的指向实例的that
try {
// 执行new Promise() 内传入的方法
fn(MyPromise.resolve, MyPromise.reject);
} catch (error) {
MyPromise.reject(this.value);
}
}
/**
* 静态resolve方法,MyPromise实例不可访问;
* 支持类MyPromise访问,例:MyPromise.resolve('success').then(e=>e)
* @param value
*/
static resolve(value) {
const that = MyPromise.that; // 由于静态方法内的this访问的是类还不是实例,所以使用这种办法访问对象实例
const f = that instanceof MyPromise; // 确认是否是MyPromise实例访问resolve
// MyPromise 实例访问resolve,如果访问成功 状态改变、值改变
if (f && that.status === that.statusObj.PENDING) {
that.status = that.statusObj.RESOLVED;
that.value = value;
that.resolvedCallBacks.map(cb => that.value = cb(that.value));
}
// MyPromise 类访问resolve
if (!f) {
const obj = new MyPromise();
return Object.assign(obj, {
status: obj.statusObj.RESOLVED,
value
})
}
}
/**
* 静态resolve方法
* @param value
*/
static reject(value) {
const that = MyPromise.that;
const f = that instanceof MyPromise;
if (f && that.status === that.statusObj.REJECTED) {
that.status = that.statusObj.REJECTED;
that.value = value;
that.rejectedCallBacks.map(cb => that.value = cb(that.value));
}
if (!f) {
const obj = new MyPromise();
return Object.assign(obj, {
status: that.statusObj.REJECTED,
value
})
}
}
/**
* MyPromise 原型上的then方法
* @param onFulfilled
* @param onRejected
*/
then(onFulfilled, onRejected) {
const { PENDING, RESOLVED, REJECTED } = this.statusObj;
const f = typeof onFulfilled == 'function' ? onFulfilled : c => c
const r = typeof onRejected == 'function' ? onRejected : c => { throw c };
switch (this.status) {
case PENDING: // PENDING 状态下 向下回调函数结合添加callback
this.resolvedCallBacks.push(f);
this.rejectedCallBacks.push(r);
break;
case RESOLVED:
this.value = f(this.value); // 将回调函数的返回值赋值给实例的 value ,满足链式调用then方法时传递value
break;
case REJECTED:
this.value = r(this.value); // 将回调函数的返回值赋值给实例的 value ,满足链式调用then方法时传递value
break;
default:
break;
}
// 满足链式调用then,返回MyPromise实例对象
return this
}
}
// new 一个Promise进行测试
MyPromise.resolve('success').then((e) => {
console.log(e);
return e + 1;
}).then((res) => {
console.log(res);
});
new MyPromise(resolve => {
setTimeout(() => {
resolve(1)
}, 2000);
})
.then((res2) => {
console.log(res2);
return 2;
}).then((res3) => {
console.log(res3);
})
那么合乎Promises/A+规范的Promise后续收集到了再添加进去吧。。。