基于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打包工具整合到鼠标右键的方法
May 11 NodeJs
nodejs分页类代码分享
Jun 17 NodeJs
我的NodeJs学习小结(一)
Jul 06 NodeJs
nodejs npm package.json中文文档
Sep 04 NodeJs
nodejs批量修改文件编码格式
Jan 22 NodeJs
NodeJS实现阿里大鱼短信通知发送
Jan 17 NodeJs
Nodejs下DNS缓存问题浅析
Nov 16 NodeJs
详解NodeJS框架express的路径映射(路由)功能及控制
Mar 24 NodeJs
nodejs+websocket实时聊天系统改进版
May 18 NodeJs
nodejs实现套接字服务功能详解
Jun 21 NodeJs
详解nodejs 配置文件处理方案
Jan 02 NodeJs
nodejs语言实现验证码生成功能的示例代码
Oct 13 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
一个简单的MySQL数据浏览器
2006/10/09 PHP
可定制的PHP缩略图生成程式(需要GD库支持)
2007/03/06 PHP
cmd下运行php脚本
2008/11/25 PHP
PHP字符串的递增和递减示例介绍
2014/02/11 PHP
PHP也能干大事 随机函数
2015/04/14 PHP
增强的 JavaScript 的 trim 函数的代码
2007/08/13 Javascript
JScript 脚本实现文件下载 一般用于下载木马
2009/10/29 Javascript
Angular中的Promise对象($q介绍)
2015/03/03 Javascript
JS定义类的六种方式详解
2016/05/12 Javascript
BootStrap Datepicker 插件修改为默认中文的实现方法
2017/02/10 Javascript
解决Vue打包之后文件路径出错的问题
2018/03/06 Javascript
javascript中floor使用方法总结
2019/02/02 Javascript
详解jQuery设置内容和属性
2019/04/11 jQuery
[43:47]完美世界DOTA2联赛PWL S3 LBZS vs Phoenix 第一场 12.09
2020/12/11 DOTA
python求列表交集的方法汇总
2014/11/10 Python
基于pip install django失败时的解决方法
2018/06/12 Python
Python利用requests模块下载图片实例代码
2019/08/12 Python
python对常见数据类型的遍历解析
2019/08/27 Python
python-tornado的接口用swagger进行包装的实例
2019/08/29 Python
浅析Python迭代器的高级用法
2020/07/16 Python
一个入门级python爬虫教程详解
2021/01/27 Python
Keds官方网站:购买帆布运动鞋和经典皮鞋
2016/11/12 全球购物
美国性感女装网站:bebe
2017/03/04 全球购物
查询优化的一般准则有哪些
2015/03/08 面试题
EJB的基本架构
2016/09/22 面试题
人力资源专员岗位职责
2014/01/30 职场文书
运动会稿件200字
2014/02/07 职场文书
《小小竹排画中游》教学反思
2014/02/26 职场文书
篮球社团活动总结
2014/06/27 职场文书
个人四风问题对照检查材料
2014/09/26 职场文书
学校艾滋病宣传活动总结
2015/05/09 职场文书
建党伟业电影观后感
2015/06/01 职场文书
关于军训的感想
2015/08/07 职场文书
餐厅开业活动方案
2019/07/08 职场文书
vue中data改变后让视图同步更新的方法
2021/03/29 Vue.js
R9700摩机记
2022/04/05 无线电