基于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中的非阻塞方法介绍
Jun 05 NodeJs
在NodeJS中启用ECMAScript 6小结(windos以及Linux)
Jul 15 NodeJs
轻松创建nodejs服务器(7):阻塞操作的实现
Dec 18 NodeJs
nodejs中使用HTTP分块响应和定时器示例代码
Mar 19 NodeJs
详解使用nodeJs安装Vue-cli
May 17 NodeJs
nodejs制作爬虫实现批量下载图片
May 19 NodeJs
详解nodeJS之二进制buffer对象
Jun 03 NodeJs
详解nodejs通过代理(proxy)发送http请求(request)
Sep 22 NodeJs
nodejs实现OAuth2.0授权服务认证
Dec 27 NodeJs
详解nodeJs文件系统(fs)与流(stream)
Jan 24 NodeJs
nodejs实现的简单web服务器功能示例
Mar 15 NodeJs
分享node.js实现简单登录注册的具体代码
Apr 26 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
smarty实例教程
2006/11/19 PHP
php 判断访客是否为搜索引擎蜘蛛的函数代码
2011/07/29 PHP
php过滤html标记属性类用法实例
2014/09/23 PHP
PHP的引用详解
2015/02/22 PHP
Laravel模型事件的实现原理详解
2018/03/14 PHP
laravel 使用事件系统统计浏览量的实现
2019/10/16 PHP
jQuery瀑布流插件Wookmark使用实例
2014/04/02 Javascript
javascript解决IE6下hover问题的方法
2015/07/28 Javascript
jQuery Validate验证框架经典大全
2015/09/23 Javascript
jQuery-1.9.1源码分析系列(十)事件系统之事件包装
2015/11/20 Javascript
使用angularjs创建简单表格
2016/01/21 Javascript
jquery树形菜单效果的简单实例
2016/06/06 Javascript
BootStrap日期控件在模态框中选择时间下拉菜单无效的原因及解决办法(火狐下不能点击)
2016/08/18 Javascript
深入理解Vue父子组件生命周期执行顺序及钩子函数
2018/08/12 Javascript
三分钟教你用Node做一个微信哄女友(基友)神器(面向小白)
2019/06/21 Javascript
js实现贪吃蛇小游戏
2019/10/29 Javascript
VUE前端从后台请求过来的数据进行转换数据结构操作
2020/11/11 Javascript
[03:49]显微镜下的DOTA2第十五期—VG登基之路完美团
2014/06/24 DOTA
python的Tqdm模块的使用
2018/01/10 Python
浅谈Python的list中的选取范围
2018/11/12 Python
python redis 删除key脚本的实例
2019/02/19 Python
浅析Python与Mongodb数据库之间的操作方法
2019/07/01 Python
python单向循环链表原理与实现方法示例
2019/12/03 Python
Python面向对象之私有属性和私有方法应用案例分析
2019/12/31 Python
python unichr函数知识点总结
2020/12/16 Python
使用 css3 实现圆形进度条的示例
2017/07/05 HTML / CSS
历史学专业大学生找工作的自我评价
2013/10/16 职场文书
学期自我评价
2014/01/27 职场文书
应聘销售主管的求职信
2014/04/26 职场文书
小学生竞选班干部演讲稿(5篇)
2014/09/12 职场文书
教师批评与自我批评范文
2014/10/15 职场文书
三八节活动简报
2015/07/20 职场文书
优质护理心得体会
2016/01/22 职场文书
初中语文教学反思范文
2016/03/03 职场文书
Python编解码问题及文本文件处理方法详解
2021/06/20 Python
centos环境下nginx高可用集群的搭建指南
2022/07/23 Servers