基于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中Buffer模块详解
Jan 07 NodeJs
浅谈Nodejs应用主文件index.js
Aug 28 NodeJs
nodejs的HTML分析利器node-jquery用法浅析
Nov 08 NodeJs
Nodejs进阶:基于express+multer的文件上传实例
Nov 21 NodeJs
async/await与promise(nodejs中的异步操作问题)
Mar 03 NodeJs
详解nodejs微信公众号开发——1.接入微信公众号
Apr 10 NodeJs
Nodejs实现多房间简易聊天室功能
Jun 20 NodeJs
NodeJs中express框架的send()方法简介
Jun 20 NodeJs
Nodejs+express+ejs简单使用实例代码
Sep 18 NodeJs
Nodejs调用WebService的示例代码
Sep 29 NodeJs
nodeJS与MySQL实现分页数据以及倒序数据
Jun 05 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 防止单引号,双引号在接受页面转义
2008/07/10 PHP
PHP 文件上传全攻略
2010/04/28 PHP
php批量更改数据库表前缀实现方法
2013/10/26 PHP
php中将一段数据存到一个txt文件中并显示其内容
2014/08/15 PHP
PHP函数func_num_args用法实例分析
2015/12/07 PHP
PHP 使用 Imagick 裁切/生成缩略图/添加水印自动检测和处理 GIF
2016/02/19 PHP
JavaScript程序员应该知道的45个实用技巧
2014/03/04 Javascript
jQuery 中$(this).index与$.each的使用指南
2014/11/20 Javascript
js获取浏览器基本信息大全
2014/11/27 Javascript
js实现带圆角的多级下拉菜单效果
2015/08/28 Javascript
js中最容易被忽视的事件问题大总结
2016/05/15 Javascript
JavaScript实现窗口抖动效果
2016/10/19 Javascript
使用vue实现点击按钮滑出面板的实现代码
2017/01/10 Javascript
jQuery学习之DOM节点的插入方法总结
2017/01/22 Javascript
javascript数据类型详解
2017/02/07 Javascript
Angular在一个页面中使用两个ng-app的方法(二)
2017/02/20 Javascript
Vue 组件传值几种常用方法【总结】
2018/05/28 Javascript
在vue项目中正确使用iconfont的方法
2018/09/28 Javascript
详解vue3.0 diff算法的使用(超详细)
2020/07/01 Javascript
vue使用element-ui实现表单验证
2020/12/13 Vue.js
浅谈python写入大量文件的问题
2018/11/09 Python
Python实现定时自动关闭的tkinter窗口方法
2019/02/16 Python
Python多进程入门、分布式进程数据共享实例详解
2019/06/03 Python
python用win32gui遍历窗口并设置窗口位置的方法
2019/07/26 Python
详解python中自定义超时异常的几种方法
2019/07/29 Python
Django后台管理系统的图文使用教学
2020/01/20 Python
python GUI库图形界面开发之PyQt5单选按钮控件QRadioButton详细使用方法与实例
2020/02/28 Python
什么是Python中的匿名函数
2020/06/02 Python
基于PyTorch的permute和reshape/view的区别介绍
2020/06/18 Python
HTML5+CSS3实例 :canvas 模拟实现电子彩票刮刮乐代码
2016/12/30 HTML / CSS
加拿大著名时装品牌:SOIA & KYO
2016/08/23 全球购物
卡塔尔航空官方网站:Qatar Airways
2017/02/08 全球购物
水污染治理专业毕业生推荐信
2013/11/14 职场文书
教师实习自我鉴定
2013/12/18 职场文书
合作协议书范文
2014/08/20 职场文书
付款承诺函范文
2015/01/21 职场文书