一个简单Promise的实现

in JavaScript with 0 comment

前言

ES6的异步处理非常方便,也非常优雅,在GitHub上面也有很多开源的接口,不过,Promise具体是怎么实现的呢?我们不妨自己动手写一个小的demo.

分析

我们首先来回顾一下Promise的基本用法:

new Promise(function(resolve , reject){
// 根据不同条件来判断执行不同的方法
if(...){
    resolve();
}else{
    reject();
}
}).then(function(){
// this is resolve
// do something
} , function(){
// this is reject
// do something
})

当我们在生成一个Promise的时候,会给他传入一个闭包,执行之后会根据我们的条件来决定执行哪个函数,resolve对应then中的第一个函数,reject对应第二个。众所周知,其实Promise中是有一个状态来判断当前执行到哪一步的,PENDING表示初始化,FULLFILL表示已完成,REJECT表示执行失败。因此,我们首先要做的第一件事情就是给他设置状态,以及我们实例化的时候需要做的准备工作:

//定义状态
const PENDING = 0;
const FULLFILL = 1;
const REJECT = 2;
function Promise(cb){
    this.status = PENDING;
// 用于接收传值
    this.value = '';
// 用于存储
    this.deffers = [];
// 通过setTimeout置于最后执行,cb.call(this)会返回一个闭包函数,剩下的两个会返回一个闭包作为参数执行
    setTimeout(cb.bind(this , this.resolve.bind(this) , this.reject.bind(this)) , 0);
}

通过上面的初始化工作,可以帮助我们去执行我们传入的回调函数,但是问题就来了,我们现在没有resolvereject这两个方法,因此,接下来一步就是在原型链上加上这两个方法:

Promise.prototype = {
    constructor : Promise,
    resolve : function(value){
        this.status = FULLFILL;
        this.value = value;
        this.done();
    },
    resolve : function(value){
        this.status = REJECT;
        this.value = value;
        this.done();
    },
    done : function(){
        this.deffers.map(function(item){
            this.handler(item);
        }.bind(this));
    },
    handler : function(item){
        if(this.status == FULLFILL){
            item.success(this.value);
        }else if(this.status == REJECT){
            item.fail(this.value);
        }
    }
}

通过上面的步骤,我们可以看到,会遍历this.deffers然后把其作为参数传入this.handler来执行,我们可以看到:item是有successfail方法的,因此,这个时候我们的then就派上了:

Promise.prototype.then = function(success , fail){
    this.deffers.push({
        success : success , 
        fail    : fail
    });
}

至此,一个简单的Promise就得以实现了,我们可以做个简单的测试:

new Promise(function(resolve , reject){
    resolve('nine');
}).then(function(value){
    console.log('this is resolve , value is : ' + value);
})

结果输出:this is resolve , value is : nine.
当然,只做到这里是远远不够的,还有then的链式调用,promisifyall等方法有待我们进一步实现。

Responses