前言
在对Promise标准规范内容有了一定了解之后,接下来,笔者将会通过ES5函数,ES6class,TypeScript的形式来单撸自己的Promise。希望对正在阅读的你有所帮助。
面试必备-手写简单的Promise
在面试的过程中,我们不可能把Promise的标准内容给面试官过一遍,面试官也不会去让你给他上一课,那么能让面试官满意,又不会花太长的时间呢?来!上电脑,直接单撸简版Promise岂不美哉!(果然内心笑出了猪叫...)
话不多说,直接上代码
// 定义常量用于表示 Promise的三种状态
const PENDING = "pending";
const RESOLVED = "resolved";
const REJECTED = "rejected";
function MyPromise(executor){
const that = this;
// 初始化状态为pending
that.state = PENDING;
// value 用于保存resolve传入的值
that.value = null;
// reason 用于保存reject传入的值
that.reason = null;
// 用于保存resolve的then的回调
that.resovledCallbacks = [];
// 用于保存reject的then的回调
that.rejectedCallbacks = [];
function resolve(value){
if(that.state === PENDINg){
that.state = RESOLVED;
that.value = value;
that.resovledCallbacks.map(cb => cb(that.value));
}
}
function reject(reason){
if(that.state === REJECTED){
that.state = REJECTED;
that.value = value;
that.rejectedCallbacks.map(cb => cb(that.reason));
}
}
// 执行MyPromise中传入的函数
try{
executor(resolve, reject);
}catch(e){
reject(e)
}
}
函数MyPromise比较好理解,首先定义三种状态,然后对参数进行初始化处理,其次创建两个数组来分别保存resolve和reject执行的then回调。最后再执行MyPromise传入的函数,这里使用了try/catch来捕获可能抛出的异常。实现了MyPromise函数之后,下面我们再看一下then函数的简单实现。
MyPromise.prototype.then = function(onFulfilled, onRejected){
const that = this;
// 判断两个参数类型,如果不是函数参数,则创建一个函数赋值给对应的参数,同时也实现了透传
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : v => v;
onRejected = typeof onRejected === 'function' ? onRejected : r => { throw r};
// 判断当前状态值,根据不同state执行相应处理逻辑
if(that.state === PENDING){
that.resovledCallbacks.push(onFulfilled);
that.rejectedCallbacks.push(onRejected);
}
if(that.state === RESOLVED){
onFulfilled(that.value);
}
if(that.state === REJECTED){
onRejected(that.reason);
}
}
到此,简单版Promisej基本上已经完成,大体上已经实现了Promise标准的骨架了,足以用来面试的临场发挥了,下面我们就写点代码来测试我们自己的代码啦(独白:自己写的代码怎么会有bug)。
养成良好的测试代码习惯,更有助于我们写出高质量的代码和高效率的完成工作。所以对于前端的测试还是要知道怎么使用的。因为这个不是本文的重点,这里不再赘述。
new MyPromise(function(resolve,reject){
setTimeout(function(){
resolve(1)
})
}).then(function(value){
console.log(value); // 1,符合预期
})
总结
好了,我们已经完成了简单版的Promise实现,是不是感觉很简单呢?如果不是很懂的话,最好多撸(这里指的是代码)几遍,然后再对着Promise规范加以理解,基本上没什么问题了。
预告:简版的Promimse虽然已经能够应付面试官,严格来说,它是不符合Promise/A+,是不能体现出我们真正对Promise的理解,下一篇文章,我将会严格按照Promise/A+的标准,一步一步的实现完整版的符合Promise/A+的Promise(期待ing...)。
完整代码
// 定义常量用于表示 Promise的三种状态
const PENDING = "pending";
const RESOLVED = "resolved";
const REJECTED = "rejected";
function MyPromise(executor){
const that = this;
// 初始化状态为pending
that.state = PENDING;
// value 用于保存resolve传入的值
that.value = null;
// reason 用于保存reject传入的值
that.reason = null;
// 用于保存resolve的then的回调
that.resovledCallbacks = [];
// 用于保存reject的then的回调
that.rejectedCallbacks = [];
function resolve(value){
if(that.state === PENDINg){
that.state = RESOLVED;
that.value = value;
that.resovledCallbacks.map(cb => cb(that.value));
}
}
function reject(reason){
if(that.state === REJECTED){
that.state = REJECTED;
that.value = value;
that.rejectedCallbacks.map(cb => cb(that.reason));
}
}
// 执行MyPromise中传入的函数
try{
executor(resolve, reject);
}catch(e){
reject(e)
}
}
MyPromise.prototype.then = function(onFulfilled, onRejected){
const that = this;
// 判断两个参数类型,如果不是函数参数,则创建一个函数赋值给对应的参数,同时也实现了透传
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : v => v;
onRejected = typeof onRejected === 'function' ? onRejected : r => { throw r};
// 判断当前状态值,根据不同state执行相应处理逻辑
if(that.state === PENDING){
that.resovledCallbacks.push(onFulfilled);
that.rejectedCallbacks.push(onRejected);
}
if(that.state === RESOLVED){
onFulfilled(that.value);
}
if(that.state === REJECTED){
onRejected(that.reason);
}
}
(译)Promise与异步编程(一):Promises / A+翻译版
喜欢的,还望给小的一波素质三连(点赞评论+关注),我会继续努力的!持续更新中..