基于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访问ActiveX对象,以操作Access数据库为例。
Dec 15 NodeJs
Nodejs中读取中文文件编码问题、发送邮件和定时任务实例
Jan 01 NodeJs
nodejs中的fiber(纤程)库详解
Mar 24 NodeJs
nodejs实现邮件发送服务实例分享
Mar 29 NodeJs
配置nodejs环境的方法
May 13 NodeJs
docker中编译nodejs并使用nginx启动
Jun 23 NodeJs
详解nodejs实现本地上传图片并预览功能(express4.0+)
Jun 28 NodeJs
nodejs判断文件、文件夹是否存在及删除的方法
Nov 10 NodeJs
nodejs实现超简单生成二维码的方法
Mar 17 NodeJs
nodejs文件夹深层复制功能
Sep 03 NodeJs
NodeJs内存占用过高的排查实战记录
May 10 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加密扩展库Mcrypt安装和实例
2013/11/10 PHP
老生常谈PHP面向对象之解释器模式
2017/05/17 PHP
PHP微信开发之微信录音临时转永久存储
2018/01/26 PHP
ie支持function.bind()方法实现代码
2012/12/27 Javascript
JQGrid的用法解析(列编辑,添加行,删除行)
2013/11/08 Javascript
input:checkbox多选框实现单选效果跟radio一样
2014/06/16 Javascript
jQuery实现的简单折叠菜单(折叠面板)效果代码
2015/09/16 Javascript
javascript html5 canvas实现可拖动省份的中国地图
2016/03/11 Javascript
jQuery Mobile 和 Kendo UI 的比较
2016/05/05 Javascript
javascript ES6中箭头函数注意细节小结
2017/02/17 Javascript
jQuery实现拖动效果的实例代码
2017/06/25 jQuery
jquery鼠标悬停导航下划线滑出效果
2017/09/29 jQuery
json前后端数据交互相关代码
2018/09/19 Javascript
react PropTypes校验传递的值操作示例
2020/04/28 Javascript
微信小程序中data-key属性之数据传输(经验总结)
2020/08/22 Javascript
解决ant design vue中树形控件defaultExpandAll设置无效的问题
2020/10/26 Javascript
[01:02:09]Liquid vs TNC 2019国际邀请赛淘汰赛 胜者组 BO3 第二场 8.21
2020/07/19 DOTA
python 字符串和整数的转换方法
2018/06/25 Python
Python爬虫之pandas基本安装与使用方法示例
2018/08/08 Python
python抓取搜狗微信公众号文章
2019/04/01 Python
python读写csv文件实例代码
2019/07/05 Python
python调用接口的4种方式代码实例
2019/11/19 Python
Django 路由层URLconf的实现
2019/12/30 Python
浅析Django 接收所有文件,前端展示文件(包括视频,文件,图片)ajax请求
2020/03/09 Python
Python socket处理client连接过程解析
2020/03/18 Python
详解Python中的路径问题
2020/09/02 Python
请写出 float x 与"零值"比较的 if 语句
2016/01/04 面试题
房地产还款计划书
2014/01/10 职场文书
运动会入场词100字
2014/02/06 职场文书
刑事辩护授权委托书范本
2014/10/17 职场文书
2014财产信托协议书范本
2014/11/18 职场文书
采购部年度工作总结
2015/08/13 职场文书
合理化建议书范文
2015/09/14 职场文书
MySQL索引篇之千万级数据实战测试
2021/04/05 MySQL
VUE使用draggable实现组件拖拽
2022/04/06 Vue.js
零基础学java之带返回值的方法的定义和调用
2022/04/10 Java/Android