基于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学习笔记之Connect中间件应用实例
Jan 27 NodeJs
nodejs实例解析(输出hello world)
Jan 03 NodeJs
NodeJS配置HTTPS服务实例分享
Feb 19 NodeJs
NodeJS处理Express中异步错误
Mar 26 NodeJs
详解使用nodeJs安装Vue-cli
May 17 NodeJs
NodeJS实现微信公众号关注后自动回复功能
May 31 NodeJs
使用Nodejs连接mongodb数据库的实现代码
Aug 21 NodeJs
nodejs 十六进制字符串型数据与btye型数据相互转换
Jul 30 NodeJs
CentOS7中源码编译安装NodeJS的完整步骤
Oct 13 NodeJs
Nodejs中获取当前函数被调用的行数及文件名详解
Dec 12 NodeJs
nodejs实现聊天机器人功能
Sep 19 NodeJs
nodejs实现UDP组播示例方法
Nov 04 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实现socket推送技术的示例
2017/12/20 PHP
javascript innerHTML使用分析
2010/12/03 Javascript
js中Image对象以及对其预加载处理示例
2013/11/20 Javascript
js子页面获取父页面数据示例
2014/05/15 Javascript
JQEasy-ui在IE9以下版本中二次加载的问题分析及处理方法
2014/06/23 Javascript
上传文件返回的json数据会被提示下载问题解决方案
2014/12/03 Javascript
javascript文件加载管理简单实现方法
2015/07/25 Javascript
jQuery EasyUI提交表单验证
2016/07/19 Javascript
jQuery实现将div中滚动条滚动到指定位置的方法
2016/08/10 Javascript
Vue.js每天必学之构造器与生命周期
2016/09/05 Javascript
基于jQuery实现照片墙自动播放特效
2017/01/12 Javascript
JavaScript下拉菜单功能实例代码
2017/03/01 Javascript
微信小程序之购物车功能
2020/09/23 Javascript
node.js学习之事件模块Events的使用示例
2017/09/28 Javascript
使用nodejs+express实现简单的文件上传功能
2017/12/27 NodeJs
Vue中的验证登录状态的实现方法
2019/03/09 Javascript
layer.confirm点击第一个按钮关闭弹出框的方法
2019/09/09 Javascript
layui表格 返回的数据状态异常的解决方法
2019/09/10 Javascript
jquery 键盘事件 keypress() keydown() keyup()用法总结
2019/10/23 jQuery
微信小程序wx.request的简单封装
2019/11/13 Javascript
Python中优化NumPy包使用性能的教程
2015/04/23 Python
Python基于property实现类的特性操作示例
2018/06/15 Python
python读写LMDB文件的方法
2018/07/02 Python
flask框架使用orm连接数据库的方法示例
2018/07/16 Python
python 实现批量xls文件转csv文件的方法
2018/10/23 Python
Python 元组操作总结
2019/09/18 Python
Jupyter Notebook 远程访问配置详解
2021/01/11 Python
请解释接口的显式实现有什么意义
2012/05/26 面试题
租房协议书
2014/04/10 职场文书
微电影大赛策划方案
2014/06/05 职场文书
软环境建设心得体会
2014/09/09 职场文书
2015年办公室人员工作总结
2015/05/15 职场文书
python如何读取.mtx文件
2021/04/22 Python
python 模块重载的五种方法
2021/04/24 Python
Django对接elasticsearch实现全文检索的示例代码
2021/08/02 Python
windows10声卡驱动怎么安装?win10声卡驱动安装操作步骤教程
2022/08/05 数码科技