Promise的实现原理

以下是promise的简单实现

var Deferred = function () {
  this.promise = new Promise();
};

var Promise = function () {
  this.queue = [];
  this.isPromise = true; //判断是否返回了一个promise对象
}

Promise.prototype.then = function (fulfilledHandler,errorHandler,progressHandler) {
   var handler = {};
   if(typeof fulfilledHandler === 'function'){
     handler.fulfilled = fulfilledHandler;
   }
  if(typeof errorHandler === 'function'){
    handler.error = errorHandler;
  }
  this.queue.push(handler);
  return this;
}

//生成回调函数
Deferred.prototype.callback = function () {
   var that = this;
   return function (err,file) {
     if(err){
       return that.reject(err);
     }
     that.resolve(file);
   }
}

Deferred.prototype.resolve = function (obj) {
  var promise = this.promise;
  var handler;
  while(handler = promise.queue.shift()){
     if(handler && handler.fulfilled){
       var ret = handler.fulfilled(obj);
       if(ret &&ret.isPromise){
         ret.queue = promise.queue;
         this.promise = ret;
         return ret;
       }
     }
  }
}

Deferred.prototype.reject = function (err) {
   var promise = this.promise,handler;
   while(handler = promise.queue.shift()){
     if(handler && handler.error){
       var ret = handler.error(err);
       if(ret && ret.isPromise){
         ret.queue = promise.queue;
         this.promise = ret;
         return ;
       }
     }
   }
}

这里我们以两次文件读取为例子,以验证该设计的可行性。这里假设读取第二个文件是依赖于第一个文件中的内容的,相关代码如下:

var readFile1 = function (file,encoding) {
   var deferred = new Deferred();
    fs.readFile(file,encoding,deferred.callback());
    return deferred.promise;
}

var readFile2 = function (file,encoding) {
  var deferred = new Deferred();
  fs.readFile(file,encoding,deferred.callback());
  return deferred.promise;
}

readFile1('file1.txt','utf8').then(function (file1) {
   return readFile2(file1.trim(),'utf8');
}).then(function (file2) {
   console.log(file2);
});

要让Promise支持链式执行,主要通过以下两个步骤
(1)将所有的回调都存放在队列中
(2)Promise完成时,逐个执行回调,一旦检测到返回了新的Promise对象,停止执行,然后将当前
deferred对象的Promise引用改变为新的Promise对象,并将队列中余下的回调转交给它。

这里的代码主要用于研究Promise的执行原理,在更多细节的优化方面,Q或者when等Promise库做得更好,实际应用时请采用这些成熟库。

注意:Promise.prototype.then的函数实现中return this;才实现了链式调用,this指代的是当前promise实例。

你可能感兴趣的:(Promise相关)