var events = require("events"); var util= require("util"); var EventEmitter = events.EventEmitter; var Defered = function(){ this.promise = new Promise(); }; /* * 从第一个defer对象的promise的queue中取出handler并执行 * 如果这个hanler返回一个proimse对象,则把第一个defer对象的promise的queue复制给这个返回 * 的promise对象,并且把第一个defer对象的Promise更新为这个返回的promise对象,从而能在第一个 * 对象的promise上实现链接调用 * */ Defered.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; } } } }; Defered.prototype.reject = function(err){ var promise = this.promise; var 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; } } } }; /** * 这个函数会被做为异步的回函数来使用 * 当异步返回时,这个函数会被执行 * 就会触发成功或失败,并把数据传递出去 * */ Defered.prototype.callback = function(){ var that = this; return function(err, file){ if(err){ return that.reject(err); } that.resolve(file); } }; function Promise(){ EventEmitter.call(this); this.queue = []; this.isPromise = true; }; util.inherits(Promise, EventEmitter); /** * * r1会返回一个promise * r1.then().then() * 通过链接调用把所有的then中的回调函数都推入第一个defer对象的promise对象的queue中 * * **/ Promise.prototype.then = function(fulfiledHandler, errorHandler, progressHandler){ var handler = {}; if(typeof fulfiledHandler === 'function'){ handler.fulfilled = fulfiledHandler; } if(typeof errorHandler === 'function'){ handler.error = errorHandler; } this.queue.push(handler); return this; }; module.exports = Defered; //这里是实例的使用 var fs = require('fs'); var defer = require("./ListPormise"); var r1 = function(file, encoding){ var d = new defer(); fs.readFile(file, encoding, d.callback()); return d.promise; }; var r2 = function(file, encoding){ var d = new defer(); fs.readFile(file, encoding, d.callback()); return d.promise; }; r1('demo.txt','utf8').then(function(file1){ return r2(file1.trim(),'utf8'); }).then(function(file2){ console.log(file2); });