基于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 相关文章推荐
Ubuntu中搭建Nodejs开发环境过程分享
Jun 01 NodeJs
nodejs的10个性能优化技巧
Jul 15 NodeJs
Nodejs极简入门教程(二):定时器
Oct 25 NodeJs
Nodejs中调用系统命令、Shell脚本和Python脚本的方法和实例
Jan 01 NodeJs
Nodejs中使用captchapng模块生成图片验证码
May 18 NodeJs
NodeJS父进程与子进程资源共享原理与实现方法
Mar 16 NodeJs
详解nodejs通过响应回写的方式渲染页面资源
Apr 07 NodeJs
nodejs中用npm初始化来创建package.json的实例讲解
Oct 10 NodeJs
Nodejs libuv运行原理详解
Aug 21 NodeJs
Nodejs实现图片上传、压缩预览、定时删除功能
Oct 25 NodeJs
nodejs开发一个最简单的web服务器实例讲解
Jan 02 NodeJs
nodeJs的安装与npm全局环境变量的配置详解
Jan 06 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
Windows中使用计划任务自动执行PHP程序实例
2014/05/09 PHP
PHP合并discuz用户脚本的方法
2015/08/04 PHP
PHP共享内存用法实例分析
2016/02/12 PHP
ThinkPHP 整合Bootstrap Ajax分页样式
2016/12/23 PHP
javascript深入理解js闭包
2010/07/03 Javascript
Nodejs极简入门教程(三):进程
2014/10/27 NodeJs
js实现点击向下展开的下拉菜单效果代码
2015/09/01 Javascript
js中substr,substring,indexOf,lastIndexOf,split,replace的用法详解
2015/11/09 Javascript
javascript实现滚动效果的数字时钟实例
2016/07/21 Javascript
jquery 动态增加删除行的简单实例(推荐)
2016/10/12 Javascript
jQuery插件echarts设置折线图中折线线条颜色和折线点颜色的方法
2017/03/03 Javascript
jquery的 filter()方法使用教程
2018/03/22 jQuery
纯JS实现出生日期[年月日]下拉菜单效果
2018/06/01 Javascript
element-ui 关于获取select 的label值方法
2018/08/24 Javascript
详解ES6系列之私有变量的实现
2018/11/21 Javascript
微信小程序生成二维码的示例代码
2019/03/29 Javascript
Vue组件系列开发之模态框
2019/04/18 Javascript
vant实现购物车功能
2020/06/29 Javascript
JavaScript Image对象实现原理实例解析
2020/08/26 Javascript
PyCharm安装第三方库如Requests的图文教程
2018/05/18 Python
对TensorFlow的assign赋值用法详解
2018/07/30 Python
pyqt5 禁止窗口最大化和禁止窗口拉伸的方法
2019/06/18 Python
python开启debug模式的方法
2019/06/27 Python
Python-Tkinter Text输入内容在界面显示的实例
2019/07/12 Python
Python 进程之间共享数据(全局变量)的方法
2019/07/16 Python
Python运算符+与+=的方法实例
2021/02/18 Python
使用HTML5做的导航条详细步骤
2020/10/19 HTML / CSS
美国单身专业人士在线约会网站:EliteSingles
2019/03/19 全球购物
领先的英国注册在线药房 :Simply Meds Online
2019/03/28 全球购物
自我鉴定200字
2013/10/28 职场文书
高校学生干部的自我评价分享
2013/11/04 职场文书
给实习单位的感谢信
2014/02/01 职场文书
竞选大队长演讲稿
2014/04/29 职场文书
导游词之上饶龟峰
2019/10/25 职场文书
tensorflow中的数据类型dtype用法说明
2021/05/26 Python
SQL Server数据库备份和恢复数据库的全过程
2022/06/14 SQL Server