基于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连接MongoDB数据库时报错的快速解决方法
May 13 NodeJs
使用nodejs中httpProxy代理时候出现404异常的解决方法
Aug 15 NodeJs
nodejs和php实现图片访问实时处理
Jan 05 NodeJs
angular2+nodejs实现图片上传功能
Mar 27 NodeJs
nodejs body-parser 解析post数据实例
Jul 26 NodeJs
nodejs 图片预览和上传的示例代码
Sep 30 NodeJs
nodejs实现爬取网站图片功能
Dec 14 NodeJs
NodeJS爬虫实例之糗事百科
Dec 14 NodeJs
nodejs实现简单的gulp打包
Dec 21 NodeJs
nodejs+koa2 实现模仿springMVC框架
Oct 21 NodeJs
nodeJs项目在阿里云的简单部署
Nov 27 NodeJs
nodejs中使用worker_threads来创建新的线程的方法
Jan 22 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
Fatal error: Call to undefined function curl_init()解决方法
2010/04/09 PHP
php+js iframe实现上传头像界面无跳转
2014/04/29 PHP
PHP dirname(__FILE__)原理及用法解析
2020/10/28 PHP
一些实用的jQuery代码片段收集
2011/07/12 Javascript
基于jQuery实现的文字按钮表单特效整理
2014/12/07 Javascript
Javascript数组与字典用法分析
2014/12/13 Javascript
使用jquery动态加载js文件的方法
2014/12/24 Javascript
JavaScript中神奇的call()方法
2015/03/12 Javascript
JS日期加减,日期运算代码
2015/11/05 Javascript
javascript实现很浪漫的气泡冒出特效
2020/09/05 Javascript
jquery特效 点击展示与隐藏全文
2015/12/09 Javascript
Nodejs全局安装和本地安装的不同之处
2016/07/04 NodeJs
jQuery中select与datalist制作下拉菜单时的区别浅析
2016/12/30 Javascript
原生js实现验证码功能
2017/03/16 Javascript
jQuery实现简单的抽奖游戏
2017/05/05 jQuery
深入理解jquery的$.extend()、$.fn和$.fn.extend()
2017/07/08 jQuery
vue-devtools的安装步骤
2018/04/23 Javascript
JS实现的透明度渐变动画效果示例
2018/04/28 Javascript
js中值引用和地址引用实例分析
2019/06/21 Javascript
在vue中利用全局路由钩子给url统一添加公共参数的例子
2019/11/01 Javascript
使用pkg打包ThinkJS项目的方法步骤
2019/12/30 Javascript
javascript实现京东登录显示隐藏密码
2020/08/02 Javascript
pygame实现弹力球及其变速效果
2017/07/03 Python
Python3一行代码实现图片文字识别的示例
2018/01/15 Python
python中正则表达式的使用方法
2018/02/25 Python
python之消除前缀重命名的方法
2018/10/21 Python
python-tkinter之按钮的使用,开关方法
2019/06/11 Python
python Xpath语法的使用
2020/11/26 Python
Java的接口和C++的虚类的相同和不同处
2014/03/27 面试题
美容院考勤制度
2014/01/30 职场文书
故宫的导游词
2015/01/31 职场文书
赞助商致辞
2015/07/30 职场文书
离婚财产分割协议书
2015/08/11 职场文书
《7的乘法口诀》教学反思
2016/02/18 职场文书
Go 语言结构实例分析
2021/07/04 Golang
我的收音机情缘
2022/04/05 无线电