您的位置:首页 > Web前端 > Node.js

node Promise/Deffered原理解析

2017-08-25 16:59 344 查看
根据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。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: