基于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 Express框架中处理404页面一个方式
May 28 NodeJs
Nodejs实现多人同时在线移动鼠标的小游戏分享
Dec 06 NodeJs
轻松创建nodejs服务器(3):代码模块化
Dec 18 NodeJs
NodeJs基本语法和类型
Feb 13 NodeJs
nodejs如何获取时间戳与时间差
Aug 03 NodeJs
深入学习nodejs中的async模块的使用方法
Jul 12 NodeJs
NodeJS使用七牛云存储上传文件的方法
Jul 24 NodeJs
Linux Centos7.2下安装nodejs&amp;npm配置全局路径的教程
May 15 NodeJs
nodejs中express入门和基础知识点学习
Sep 13 NodeJs
通过Nodejs搭建网站简单实现注册登录流程
Jun 14 NodeJs
nodejs中各种加密算法的实现详解
Jul 11 NodeJs
基于NodeJS开发钉钉回调接口实现AES-CBC加解密
Aug 20 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使用qr生成二维码的示例分享
2014/01/20 PHP
Thinkphp实现短信验证注册功能
2016/10/18 PHP
php简单构造json多维数组的方法示例
2017/06/08 PHP
密码框显示提示文字jquery示例
2013/08/29 Javascript
js 时间格式与时间戳的相互转换示例代码
2013/12/25 Javascript
javascript数组操作方法小结和3个属性详细介绍
2014/07/05 Javascript
javascript框架设计读书笔记之种子模块
2014/12/02 Javascript
JavaScript统计网站访问次数的实现代码
2015/11/18 Javascript
javascript中new关键字详解
2015/12/14 Javascript
JS实现经典的中国地区三级联动下拉菜单功能实例【测试可用】
2017/06/06 Javascript
详解vue数据渲染出现闪烁问题
2017/06/29 Javascript
JavaScript EventEmitter 背后的秘密 完整版
2018/03/29 Javascript
JavaScript事件委托原理与用法实例分析
2018/06/07 Javascript
Vue实现美团app的影院推荐选座功能【推荐】
2018/08/29 Javascript
用vue-cli开发vue时的代理设置方法
2018/09/20 Javascript
微信小程序开发技巧汇总
2019/07/15 Javascript
React学习之JSX与react事件实例分析
2020/01/06 Javascript
vue-cli3项目升级到vue-cli4 的方法总结
2020/03/19 Javascript
element-ui 实现响应式导航栏的示例代码
2020/05/08 Javascript
[19:14]DOTA2 HEROS教学视频教你分分钟做大人-维萨吉
2014/06/24 DOTA
python连接池实现示例程序
2013/11/26 Python
Python安装Numpy和matplotlib的方法(推荐)
2017/11/02 Python
python实现自主查询实时天气
2018/06/22 Python
Python读取txt内容写入xls格式excel中的方法
2018/10/11 Python
使用Python实现画一个中国地图
2019/11/23 Python
Python的形参和实参使用方式
2019/12/24 Python
python实现拼图小游戏
2020/02/22 Python
如何打开WebSphere远程debug
2014/10/10 面试题
某/etc/fstab文件中的某行如下: /dev/had5 /mnt/dosdata msdos defaults,usrquota 1 2 请解释其含义
2013/09/18 面试题
工厂保洁员岗位职责
2013/12/04 职场文书
企业消防安全制度
2014/02/02 职场文书
品牌转让协议书
2014/08/20 职场文书
2014副局长群众路线对照检查材料思想汇报
2014/09/22 职场文书
2015教师年度工作总结范文
2015/04/07 职场文书
对PyTorch中inplace字段的全面理解
2021/05/22 Python
Python 的演示平台支持 WSGI 接口的应用
2022/04/20 Python