promise的实现原理

来源:互联网 发布:手机语言翻译软件 编辑:程序博客网 时间:2024/06/05 03:50

以node EventEmitter为核心实现基础版promise

//利用node EventEmitter实现promise    var Promise = function(){        EventEmitter.call(this);//显式调用构造函数    }    util.inherits(Promise,EventEmitter);//利用node util工具函数inherits实现继承    Promise.prototype.then = function(fulfilledHandler, errorHandler, progressHandler){        if(typeof fulfilledHandler === 'function'){            this.once('success', fulfilledHandler);//利用once只调用一次        }        if(typeof errorHandler === 'function'){            this.once('error', errorHandler);        }        if(typeof progressHandler === 'function'){            this.on('progress',progressHandler);        }        return this;    }    var Deffered = function(){        this.state = 'unfulfilled';        this.promise = new Promise();    }    Deffered.prototype.resolve = function(obj){        this.state = 'fulfilled';        this.promise.emit('success',obj);    }    Deffered.prototype.reject = function(obj){        this.state = 'failed';        this.promise.emit('error',obj);    }    Deffered.prototype.progress = function(obj){        this.promise.emit('progress',obj);    }    //对一个简单的响应做封装    var promisify = function(res){        var deffered = new Deffered();        var result = '';        res.on('data', function(chunk){            result += chunk;            deffered.progress(chunk);        });        res.on('end', function(){            deffered.resolve(result);        });        res.on('error', function(err){            deffered.reject(err);        });        return deffered.promise;    }    //使用起来    promisifi(res).then(function(){},function(){},function(){});

不难看出,这里的deffered主要用于维护异步模型的状态,promise作用于外部,通过then()来添加自定义逻辑。

多异步协作应该如何实现呢?
//解决多异步协作的问题

    Deffered.prototype.all = function(promises){        var count = promises.length;        var that = this;        var results = [];        promises.forEach(function(promise,i){            promise.then(function(data){                count--;                results[i] = data;                if(count === 0){                    that.resolve(results);                }            },function(err){                that.reject(err);            });        });        return this.promise;    }    //调用多异步协作    var deffered = new Deffered();    deffered.all([promise1,promise2]).then(function(results){},function(err){})

后续思考::要想支持序列支持,即链式调用,主要需要两个步骤:
1、将所有回调逗存在队列中。
2、promise完成时,逐个执行回调,一旦检测到返回了新的promise对象,停止执行,然后将当前deffered对象的promise引用改编为新的promise对象,并将队列中余下的回调转交给新的promise。
具体实现可以参考《深入浅出nodejs》90页!~~

原创粉丝点击