node Promise/Deffered原理解析

来源:互联网 发布:外汇收入 知乎 编辑:程序博客网 时间:2024/05/21 17:21

根据promise/deferred模式

var fs = require(‘fs’);

定义Promise对象

var Promise = function(){       this.isPromise = true;//检查then中的参数(方法)返回的是不是Promise对象       this.queue = [];//用于存放then的参数,实现队列功能};Promise.prototype = {  then:function (fulfilledHandler,errHandler) {              var handler = {};              if(typeof fulfilledHandler === 'function'){                    handler.fulfilled = fulfilledHandler;         }              if(typeof errdHandler === 'function'){                       handler.error = errHandler;           }              this.queue.push(handler);//then的作用就是将他的参数push进                                                           Promise的queue数组中              return this;//返回Promise对象以实现链式调用then     }};

定义Deffered对象

var Deferred = function () {  this.promise = new Promise();};Deferred.prototype = {  resolve:function (obj) {//resolve作用就是将Promise的queue数组中的方法                                                          按序取出并执行      var promise = this.promise;      var handler;      while((handler = promise.queue.shift())){//先进先出            if(handler && handler.fulfilled){                         var ret = handler.fulfilled(obj);                         if(ret && ret.isPromise){//这里的判断很重要,若then中的方法返回的是Promise对象就像Promise对象更新为then返回的Promise,然后return,只要then中的参数返回Promise对象,则resolve的while就循环一次,这样then参数中的方法调用了resolve后才能继续向下执行,这样才能保证按顺序传递参数,相当于下一步的执行一来上一步的完成。                         ret.queque = promise.queue;                         this.promise = ret;//这里将新返回的promise对象引用指向最初的promise,因此程序执行期间只有一个promise对象                                      return;                     }          }   }},reject:function (obj) {      var promise = this.promise;      var handler;      while((handler = promise.queue.shift())){          if(handler && handler.error){                      var ret = handler.error(obj);                      if(ret && ret.isPromise){                            ret.queque = promise.queue;                          this.promise = ret;                          return;                  }               }       }},};

下面测试,首先读取zy1.txt中的内容即为then方法的参数,

var deferred = new Deferred();function f1(){     fs.readFile('zy1.txt','utf-8',function(err,file) {              if (err) {                 deferred.reject(err);         }              if(file){                  deferred.resolve(file);//只有这一步执行后才会执行第一个then中                     的方法,因为第一个then中的参数返回Promise对象,所以then中的                       while只执行一次就停止           }       });  return deferred.promise;}

链式添加then方法

f1().then(function(file1){//then 的参数不执行只是push进f1返回的Promise对象                                                 的queue数组中      console.log(file1);    fs.readFile(file1,'utf-8',function(err,file){ if (err) {         deferred.reject(err); }      if(file){          deferred.resolve(file);//只有这一步执行后才会执行第二个then中的方                   法。      }});return deferred.promise;}).then(function (file2) {      console.log(file2);});

原理分析

  • 用队列存放then中的参数,当resolve时顺序执行
  • 一旦检测到then中的参数返回Promise对象就立即停止执行,然后将当前deferred中的promise引用指向新的then中的参数返回Promise。
原创粉丝点击