基于promise.js实现nodejs的promises库

 更新时间:2014年07月06日 11:19:44   投稿:hebedich  
promise是JavaScript实现优雅编程的一个非常不错的轻量级框架。该框架可以让你从杂乱的多重异步回调代码中解脱出来,并把精力集中到你的业务逻辑上。

今天从GIT源码库中下载了promise.js,发现该源码是基于Web前端JavaScript写的,并不能直接用于nodejs。还好代码不是很多,也不是很复杂。经过分析整合,将其实现为nodejs的一个框架,代码如下:

(function(){
/**
* Copyright 2012-2013 (c) Pierre Duquesne <stackp@online.fr>
* script: promise.js
* description: promises的nodejs模块
* modified: https://github.com/stackp/promisejs
* authors: alwu007@sina.cn
* */

var Promise = exports.Promise = function(){
  this._callbacks = [];
};

Promise.prototype.then = function(func, context){
  //处理回调结果的方法
  function doCallbackResults(r) {
    if (r instanceof Promise) {
      r.then(function(err, values){
        p.done(err, values);
      });
    } else {
      p.done(null, r);
    }
  }

  var p = new Promise();
  if (this._isdone) {
    var results = func.apply(context, this.results);
    doCallbackResults(results);
  } else {
    this._callbacks.push(function(){
      var results = func.apply(context, arguments);
      doCallbackResults(results);
    });
  }
  return p;
};

Promise.prototype.done = function(){
  this.results = arguments;
  this._isdone = true;
  for (var i=0; i<this._callbacks.length; i++) {
    this._callbacks[i].apply(null, arguments);
  }
  this._callbacks = [];
};

Promise.join = function(promises){
  var p = new Promise();
  var results = [];

  if (!promises || !promises.length) {
    p.done(results);
    return p;
  }

  var numdone = 0;
  var total = promises.length;

  function notifier(i) {
    return function() {
      numdone += 1;
      results[i] = Array.prototype.slice.call(arguments);
      if (numdone === total) {
        p.done(results);
      }
    };
  }

  for (var i = 0; i < total; i++) {
    promises[i].then(notifier(i));
  }

  return p;
};

Promise.chain = function(funcs, args) {
  var p = new Promise();
  if (!funcs || !funcs.length) {
    p.done.apply(p, args);
  } else {
    funcs[0].apply(null, args).then(function(){
      funcs.splice(0, 1);
      Promise.chain(funcs, arguments).then(function(){
        p.done.apply(p, arguments);
      });
    });
  }
  return p;
};
})();

另附测试代码如下:

/**
* script: test.js
* description: promise.js测试代码
* */

var promise = require('./mypromise');

function asyncfoo() {
  var p = new promise.Promise();
  setTimeout(function(){
    p.done();
  }, 1000);
  return p;
}

function syncfoo() {
  var p = new promise.Promise();
  p.done();
  return p;
}

var o = {};
/*
asyncfoo().then(function(){
  return 'Raymond';
}, o).then(function(err, name){
  o.name = name;
  return asyncfoo().then(asyncfoo).then(function(){
    return asyncfoo().then(asyncfoo).then(function(){
      return 18;
    });
  });
}, o).then(function(err, age){
  o.age = age;
  return asyncfoo().then(asyncfoo).then(function(){
    return asyncfoo().then(asyncfoo).then(function(){
      return 'boy';
    });
  }).then(function(err, sex){
    return sex;
  });
}).then(function(err, sex){
  o.sex = sex;
  return 'Hello, world!';
}).then(function(err, say){
  o.say = say;
  console.dir(o);
});

syncfoo().then(function(){
  return 'Raymond';
}, o).then(function(err, name){
  o.name = name;
  return syncfoo().then(syncfoo).then(function(){
    return syncfoo().then(syncfoo).then(function(){
      return 18;
    });
  });
}, o).then(function(err, age){
  o.age = age;
  return asyncfoo().then(asyncfoo).then(function(){
    return asyncfoo().then(asyncfoo).then(function(){
      return 'boy';
    });
  }).then(function(err, sex){
    return sex;
  });
}).then(function(err, sex){
  o.sex = sex;
  return 'Hello, world!';
}).then(function(err, say){
  o.say = say;
  console.dir(o);
});
*/
function asyncfoo1(){
  var p = new promise.Promise();
  setTimeout(function(){
    p.done(null, 'Raymond');
  }, 1000);
  return p;
}

function asyncfoo2(err, name){
  o.name = name;
  var p = new promise.Promise();
  setTimeout(function(){
    p.done(null, 18);
  }, 1000);
  return p;
}
function asyncfoo3(err, age){
  o.age = age;
  var p = new promise.Promise();
  setTimeout(function(){
    p.done(null, 'boy');
  }, 1000);
  return p;
}
function asyncfoo4(){
  var p = new promise.Promise();
  setTimeout(function(){
    p.done(null, 'Hello, world!');
  }, 1000);
  return p;
}
promise.Promise.chain([asyncfoo1, asyncfoo2, asyncfoo3]).then(function(err, sex){
  o.sex = sex;
  return asyncfoo4();
}).then(function(err, say){
  o.say = say;
}).then(function(){
  console.dir(o);
});

相关文章

  • node + multer 实现文件上传过程

    node + multer 实现文件上传过程

    这篇文章主要介绍了node + multer 实现文件上传过程,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-09-09
  • nodejs 中模拟实现 emmiter 自定义事件

    nodejs 中模拟实现 emmiter 自定义事件

    这篇文章主要介绍了Nodejs中自定义事件实例,比较简单的一个例子,需要的朋友可以参考下。
    2016-02-02
  • iOS + node.js使用Socket.IO框架进行实时通信示例

    iOS + node.js使用Socket.IO框架进行实时通信示例

    本篇文章主要介绍了iOS + node.js使用Socket.IO框架进行实时通信示例,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。
    2017-04-04
  • npm install --save 、--save-dev 、-D、-S 的区别与NODE_ENV的配置方法

    npm install --save 、--save-dev 、-D、-S&nb

    这篇文章主要介绍了npm install --save 、--save-dev 、-D、-S 的区别与NODE_ENV的配置方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-08-08
  • node.js基于dgram数据报模块创建UDP服务器和客户端操作示例

    node.js基于dgram数据报模块创建UDP服务器和客户端操作示例

    这篇文章主要介绍了node.js基于dgram数据报模块创建UDP服务器和客户端操作,结合实例形式分析了node.js使用dgram数据报模块创建UDP服务器和客户端,以及进行UDP广播、组播相关操作技巧,需要的朋友可以参考下
    2020-02-02
  • Node.js发送HTTP客户端请求并显示响应结果的方法示例

    Node.js发送HTTP客户端请求并显示响应结果的方法示例

    这篇文章主要介绍了Node.js发送HTTP客户端请求并显示响应结果的方法,结合完整实例形式分析了nodejs发送http请求及响应的相关操作技巧,需要的朋友可以参考下
    2017-04-04
  • nodejs项目windows下开机自启动的方法

    nodejs项目windows下开机自启动的方法

    今天小编就为大家分享一篇nodejs项目windows下开机自启动的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2017-11-11
  • NodeJS学习笔记之网络编程

    NodeJS学习笔记之网络编程

    Node.js采用了Google Chrome浏览器的V8引擎,性能很好,同时还提供了很多系统级的API,如文件操作、网络编程等。Node.js则是一个全面的后台运行时,为Javascript提供了其他语言能够实现的许多功能。今天我们来看下Nodejs的网络编程
    2014-08-08
  • nodejs中的读取文件fs与文件路径path解析

    nodejs中的读取文件fs与文件路径path解析

    这篇文章主要介绍了nodejs中的读取文件fs与文件路径path解析,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-08-08
  • node.js中的buffer.Buffer.isEncoding方法使用说明

    node.js中的buffer.Buffer.isEncoding方法使用说明

    这篇文章主要介绍了node.js中的buffer.Buffer.isEncoding方法使用说明,本文介绍了buffer.Buffer.isEncoding的方法说明、语法、接收参数、使用实例和实现源码,需要的朋友可以参考下
    2014-12-12

最新评论