基于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批量修改文件编码格式
Jan 22 NodeJs
nodejs爬虫抓取数据之编码问题
Jul 03 NodeJs
Nodejs中 npm常用命令详解
Jul 04 NodeJs
NodeJs的优势和适合开发的程序
Aug 14 NodeJs
详解nodejs 文本操作模块-fs模块(四)
Dec 22 NodeJs
详解nodejs微信公众号开发——3.封装消息响应模块
Apr 10 NodeJs
Nodejs回调加超时限制两种实现方法
Jun 09 NodeJs
Nodejs实现多房间简易聊天室功能
Jun 20 NodeJs
nodejs使用express获取get和post传值及session验证的方法
Nov 09 NodeJs
CentOS7中源码编译安装NodeJS的完整步骤
Oct 13 NodeJs
nodejs 使用 js 模块的方法实例详解
Dec 04 NodeJs
基于nodejs的微信JS-SDK简单应用实现
May 21 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
关于Intype一些小问题的解决办法
2008/03/28 PHP
php面向对象全攻略 (六)__set() __get() __isset() __unset()的用法
2009/09/30 PHP
PHP计划任务、定时执行任务的实现代码
2011/04/23 PHP
PHP垃圾回收机制引用计数器概念分析
2013/06/24 PHP
zf框架db类的分页示例分享
2014/03/14 PHP
微信支付PHP SDK之微信公众号支付代码详解
2015/12/09 PHP
PHP PDOStatement::execute讲解
2019/01/31 PHP
jQuery ajax在GBK编码下表单提交终极解决方案(非二次编码方法)
2010/10/20 Javascript
js拖动div 当鼠标移动时整个div也相应的移动
2013/11/21 Javascript
js实现的二级横向菜单条实例
2015/08/22 Javascript
JS中多种方式创建对象详解
2016/03/22 Javascript
JavaScript实现垂直向上无缝滚动特效代码
2016/11/23 Javascript
jQuery插件Echarts实现的双轴图效果示例【附demo源码下载】
2017/03/04 Javascript
vue实现tab切换外加样式切换方法
2018/03/16 Javascript
浅谈vue中关于checkbox数据绑定v-model指令的个人理解
2018/11/14 Javascript
解决微信小程序调用moveToLocation失效问题【超简单】
2019/04/12 Javascript
vue router 通过路由来实现切换头部标题功能
2019/04/24 Javascript
layui type2 通过url给iframe子页面传值的例子
2019/09/06 Javascript
layui 富文本赋值,取值,取纯文本值的实例
2019/09/18 Javascript
如何在面试中手写出javascript节流和防抖函数
2020/10/22 Javascript
[02:56]DOTA2上海特锦赛小组赛解说FreeAgain采访花絮
2016/02/27 DOTA
Python基于百度AI的文字识别的示例
2018/04/21 Python
TensorFlow实现打印每一层的输出
2020/01/21 Python
Python-openpyxl表格读取写入的案例详解
2020/11/02 Python
Python Selenium破解滑块验证码最新版(GEETEST95%以上通过率)
2021/01/29 Python
使paramiko库执行命令时在给定的时间强制退出功能的实现
2021/03/03 Python
俄罗斯GamePark游戏商店网站:购买游戏、游戏机和配件
2020/03/13 全球购物
大学四年职业生涯规划书范文
2014/01/02 职场文书
便利店投资的创业计划书
2014/01/12 职场文书
建筑个人求职信范文
2014/01/25 职场文书
社区党员志愿服务活动方案
2014/08/18 职场文书
2014党员学习《反腐倡廉警示教育读本》思想汇报
2014/09/13 职场文书
员工工作能力评语
2014/12/31 职场文书
忠犬八公的故事观后感
2015/06/05 职场文书
温馨祝福晨语:美丽的一天从我的问候开始
2019/11/28 职场文书
pytorch 实现变分自动编码器的操作
2021/05/24 Python