基于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服务器(1):一个简单nodejs服务器例子
Dec 18 NodeJs
基于html5和nodejs相结合实现websocket即使通讯
Nov 19 NodeJs
nodeJs爬虫获取数据简单实现代码
Mar 29 NodeJs
详解Nodejs的timers模块
Dec 22 NodeJs
nodejs multer实现文件上传与下载
May 10 NodeJs
详解nodejs微信jssdk后端接口
May 25 NodeJs
使用Nodejs连接mongodb数据库的实现代码
Aug 21 NodeJs
nodejs操作mongodb的填删改查模块的制作及引入实例
Jan 02 NodeJs
Nodejs中crypto模块的安全知识讲解
Jan 03 NodeJs
nodejs结合Socket.IO实现的即时通讯功能详解
Jan 12 NodeJs
NodeJs搭建本地服务器之使用手机访问的实例讲解
May 12 NodeJs
Linux Centos7.2下安装nodejs&amp;npm配置全局路径的教程
May 15 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
支持oicq头像的留言簿(二)
2006/10/09 PHP
discuz加密解密函数使用方法和中文注释
2014/01/21 PHP
jquery向.ashx文件post中文乱码问题的解决方法
2011/03/28 Javascript
jquery实现将获取的颜色值转换为十六进制形式的方法
2014/12/20 Javascript
js下将金额数字每三位一逗号分隔
2016/02/19 Javascript
jQuery查看选中对象HTML代码的方法
2016/06/17 Javascript
老生常谈的跨域处理
2017/01/11 Javascript
原生js实现吸顶效果
2017/03/13 Javascript
一篇看懂vuejs的状态管理神器 vuex状态管理模式
2017/04/20 Javascript
微信小程序tabbar不显示解决办法
2017/06/08 Javascript
详解webpack进阶之插件篇
2017/07/06 Javascript
Vue2.0+ElementUI实现表格翻页的实例
2017/10/23 Javascript
layui 优化button按钮和弹出框的方法
2018/08/15 Javascript
微信小程序公用参数与公用方法用法示例
2019/01/09 Javascript
vue.js实现会动的简历(包含底部导航功能,编辑功能)
2019/04/08 Javascript
vue3.0 搭建项目总结(详细步骤)
2019/05/20 Javascript
Python编写生成验证码的脚本的教程
2015/05/04 Python
解决Python出现_warn_unsafe_extraction问题的方法
2016/03/24 Python
python数据结构链表之单向链表(实例讲解)
2017/07/25 Python
Python 爬取携程所有机票的实例代码
2018/06/11 Python
Selenium定位元素操作示例
2018/08/10 Python
pygame实现烟雨蒙蒙下彩虹雨
2019/11/11 Python
python中元组的用法整理
2020/06/15 Python
css3实现的下拉菜单效果示例
2014/01/22 HTML / CSS
详解canvas绘图时遇到的跨域问题
2018/03/22 HTML / CSS
Clearly澳大利亚:购买眼镜、太阳镜和隐形眼镜
2018/04/26 全球购物
Coggles美国/加拿大:高级国际时装零售商
2018/10/23 全球购物
纽约和芝加哥当天送花:Ode à la Rose
2019/07/05 全球购物
益模软件Java笔试题
2012/03/27 面试题
清正廉洁演讲稿
2014/05/22 职场文书
学校教研活动总结
2014/07/02 职场文书
励志演讲稿600字
2014/08/21 职场文书
大学生党员学习焦裕禄精神思想汇报
2014/09/10 职场文书
导游词之南京中山陵
2019/11/27 职场文书
利用uni-app生成微信小程序的踩坑记录
2022/04/05 Javascript
nginx.conf配置文件结构小结
2022/04/08 Servers