基于promise.js实现nodejs的promises库


Posted in NodeJs onJuly 06, 2014

今天从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);
});
NodeJs 相关文章推荐
nodejs之请求路由概述
Jul 05 NodeJs
nodejs redis 发布订阅机制封装实现方法及实例代码
Dec 15 NodeJs
NodeJS测试框架mocha入门教程
Mar 28 NodeJs
nodeJS(express4.x)+vue(vue-cli)构建前后端分离实例(带跨域)
Jul 05 NodeJs
NodeJS使用七牛云存储上传文件的方法
Jul 24 NodeJs
详解Nodejs 通过 fs.createWriteStream 保存文件
Oct 10 NodeJs
nodejs基于WS模块实现WebSocket聊天功能的方法
Jan 12 NodeJs
nodejs实现一个word文档解析器思路详解
Aug 14 NodeJs
NodeJS搭建HTTP服务器的实现步骤
Oct 12 NodeJs
Nodejs处理异常操作示例
Dec 25 NodeJs
nodejs异步编程基础之回调函数用法分析
Dec 26 NodeJs
NodeJs生成sitemap站点地图的方法示例
Jun 11 NodeJs
我的NodeJs学习小结(一)
Jul 06 #NodeJs
nodejs中使用monk访问mongodb
Jul 06 #NodeJs
nodejs之请求路由概述
Jul 05 #NodeJs
Nodejs中自定义事件实例
Jun 20 #NodeJs
Nodejs sublime text 3安装与配置
Jun 19 #NodeJs
nodejs实现黑名单中间件设计
Jun 17 #NodeJs
nodejs分页类代码分享
Jun 17 #NodeJs
You might like
php获取目标函数执行时间示例
2014/03/04 PHP
深入讲解PHP的Yii框架中的属性(Property)
2016/03/18 PHP
CodeIgniter基于Email类发邮件的方法
2016/03/29 PHP
php单元测试phpunit入门实例教程
2017/11/17 PHP
Javascript实例教程(19) 使用HoTMetal(7)
2006/12/23 Javascript
json 定义
2008/06/10 Javascript
javascript 静态对象和构造函数的使用和公私问题
2010/03/02 Javascript
JavaScript中判断对象类型的几种方法总结
2013/11/11 Javascript
深入理解Javascript作用域与变量提升
2013/12/09 Javascript
js的image onload事件使用遇到的问题
2014/07/15 Javascript
jQuery实现的一个自定义Placeholder属性插件
2014/08/11 Javascript
JavaScript编程的单例设计模讲解
2015/11/10 Javascript
轻松掌握JavaScript策略模式
2016/08/25 Javascript
jquery实时获取时间的简单实例
2017/01/26 Javascript
使用vue构建一个上传图片表单
2017/07/04 Javascript
AngularJS实现页面跳转后自动弹出对话框实例代码
2017/08/02 Javascript
vue与bootstrap实现时间选择器的示例代码
2017/08/26 Javascript
vue与TypeScript集成配置最简教程(推荐)
2017/10/17 Javascript
webpack 单独打包指定JS文件的方法
2018/02/22 Javascript
4 种滚动吸顶实现方式的比较
2019/04/09 Javascript
基于JS实现数字动态变化显示效果附源码
2019/07/18 Javascript
vue实现购物车列表
2020/06/30 Javascript
JS实现斐波那契数列的五种方式(小结)
2020/09/09 Javascript
[03:48]显微镜下的DOTA2第四期——TP动作
2014/06/20 DOTA
python获取本机mac地址和ip地址的方法
2015/04/29 Python
Python使用minidom读写xml的方法
2015/06/03 Python
Python 绘图和可视化详细介绍
2017/02/11 Python
Python数据类型之List列表实例详解
2019/05/08 Python
python 使用turtule绘制递归图形(螺旋、二叉树、谢尔宾斯基三角形)
2019/05/30 Python
带你认识HTML5中的WebSocket
2015/05/22 HTML / CSS
电子商务专业个人的自我评价
2013/11/19 职场文书
户外用品商店创业计划书
2014/01/29 职场文书
企业内控岗位的职责
2014/02/07 职场文书
团队激励口号
2014/06/06 职场文书
副主任竞聘演讲稿
2014/08/18 职场文书
《所见》教学反思
2016/02/23 职场文书