Promise与异步编程(二):单撸简版Promise

447 阅读3分钟

前言

在对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+翻译版

喜欢的,还望给小的一波素质三连(点赞评论+关注),我会继续努力的!持续更新中..