基于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 Post请求报socket hang up错误的解决办法
Sep 25 NodeJs
轻松创建nodejs服务器(5):事件处理程序
Dec 18 NodeJs
NodeJs的优势和适合开发的程序
Aug 14 NodeJs
NodeJS实现客户端js加密
Jan 09 NodeJs
详解nodeJS中读写文件方法的区别
Mar 06 NodeJs
详解nodejs操作mongodb数据库封装DB类
Apr 10 NodeJs
详解nodejs微信公众号开发——6.自定义菜单
Apr 13 NodeJs
NodeJS 实现手机短信验证模块阿里大于功能
Jun 19 NodeJs
nodejs实现范围请求的实现代码
Oct 12 NodeJs
nodejs基础之buffer缓冲区用法分析
Dec 26 NodeJs
nodejs的安装使用与npm的介绍
Sep 11 NodeJs
使用 Koa + TS + ESLlint 搭建node服务器的过程详解
May 30 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的安全策略
2006/10/09 PHP
php 上一篇,下一篇文章实现代码与原理说明
2010/05/09 PHP
php使用PDO下exec()函数查询执行后受影响行数的方法
2017/03/28 PHP
php实现页面纯静态的实例代码
2017/06/21 PHP
PHP实践教程之过滤、验证、转义与密码详解
2017/07/24 PHP
支持汉转拼和拼音分词的PHP中文工具类ChineseUtil
2018/02/23 PHP
js 静态动态成员 and 信息的封装和隐藏
2011/05/29 Javascript
Javascript 检测键盘按键信息及键码值对应介绍
2013/01/03 Javascript
JS对select控件option选项的增删改查示例代码
2013/10/21 Javascript
js构造函数、索引数组和属性的实现方式和使用
2014/11/16 Javascript
重写document.write实现无阻塞加载js广告(补充)
2014/12/12 Javascript
深入理解JavaScript系列(36):设计模式之中介者模式详解
2015/03/04 Javascript
jQuery选择器源码解读(六):Sizzle选择器匹配逻辑分析
2015/03/31 Javascript
JS实现随机乱撞彩色圆球特效的方法
2015/05/05 Javascript
深入浅出 jQuery中的事件机制
2016/08/23 Javascript
微信小程序 配置顶部导航条标题颜色的实现方法
2017/09/20 Javascript
用js实现每隔一秒刷新时间的实例(含年月日时分秒)
2017/10/25 Javascript
微信小程序实现添加手机联系人功能示例
2017/11/30 Javascript
JavaScript查看代码运行效率console.time()与console.timeEnd()用法
2019/01/18 Javascript
vue 接口请求地址前缀本地开发和线上开发设置方式
2020/08/13 Javascript
对于Python的Django框架部署的一些建议
2015/04/09 Python
Python栈类实例分析
2015/06/15 Python
浅谈Python peewee 使用经验
2017/10/20 Python
pytorch 实现模型不同层设置不同的学习率方式
2020/01/06 Python
美国室内和室外装饰花盆购物网站:ePlanters
2019/03/22 全球购物
Everlast官网:拳击、综合格斗和健身相关的体育用品
2020/08/03 全球购物
C#如何进行LDAP用户校验
2012/11/21 面试题
地理科学专业毕业生求职信
2013/10/15 职场文书
化工专业推荐信范文
2013/11/28 职场文书
文明班集体申报材料
2014/05/23 职场文书
法语专业求职信
2014/07/20 职场文书
地陪导游欢迎词
2015/01/26 职场文书
苏州园林导游词
2015/02/03 职场文书
小学教师个人总结
2015/02/05 职场文书
Python数据分析之绘图和可视化详解
2021/06/02 Python
一篇文章弄清楚Ajax请求的五个步骤
2022/03/17 Javascript