精华 promise工具包分享
发布于 8 年前 作者 magicdawn 8131 次浏览 来自 分享

听说 v8 已经着手实现 async/await 了, 可喜可贺

分享一波 promise 工具集

promise.map

跟 bluebird promise.map 一样的功能, 提供 concurrency, 这个实现的核心代码抄自很久之前的 async.parallelLimit https://github.com/magicdawn/promise.map

var map = require('promise.map');
var p = map(arr, function(item, index, arr){
  return getOtherPromise(item);
}, concurrency);

promise.delay

还是跟 bluebird 的功能一致, 实现一个 sleep 功能 https://github.com/magicdawn/promise.delay

const sleep = require('promise.delay');
sleep(100).then(function(){
  // blabla
});

promise.obj

类似 bluebird Promise.props, 实现 object 版本的 Promise.all https://github.com/magicdawn/promise.obj

const pobj = require('promise.obj');

const p = pobj({
  x: Promise.resolve('x'),
  y: Promise.resolve('y')
});

p.then(function(o){
  o.x // 'x'
  o.y // 'y'
})

promise.retry

给一个异步函数, 增加重试功能, 支持普通错误 & 超时错误. 这个貌似 bluebird 里面没有? https://github.com/magicdawn/promise.retry

const pretry = require('promise.retry');
const TimeoutError = pretry.TimeoutError;
const RetryError = pretry.RetryError;
const fnWithRetry = pretry(fn, options);

promise.timeout

给一个异步函数加上超时处理 https://github.com/magicdawn/promise.timeout

var ptimeout = require('promise.timeout');

// a function will cost 20ms
function test() {
  return new Promise(function(resolve, reject) {
    setTimeout(function() {
      resolve(20);
    }, 20);
  });
}

const test10 = ptimeout(test, 10);
const test50 = ptimeout(test, 50);

// 10 timeout
try {
  yield test10();
} catch (e) {
  e.should.be.ok();
  e.should.be.instanceof(ptimeout.TimeoutError);
  e.message.should.match(/timeout/);
  e.timeout.should.equal(10);
}

// 50 ok
const _50 = yield test50();
_50.should.be.ok();
_50.should.equal(20);

promise.ify

类似 bluebird Promise.promisify, 支持简单的 promiseifyAll, 以及noerr 处理没有 err 的 callback情况 https://github.com/magicdawn/promise.ify

var promiseify = require('promise.ify');
var readFile = promiseify(fs.readFile, fs);

var Connection = require('mysql/lib/Connection');
promiseify.all(Connection.prototype);

好的, 为什么实现 bluebird 那些方法呢, 因为不想绑死在 bluebird 上, 有一些原因要去掉 bluebird 的时候不会因为它的一些有用的方法而舍不得. 有了这些小工具库,可以选择任意Promise A+ 实现哦~都是使用的 global.Promise

注意 promise.retry 使用了 generator, 目标环境为 ES6, 其他的包都是target 到 ES5 的, 就是 browserify or webpack 直接require 即可, 不需要再次编译.

12 回复

几个都是 0 star. 不过不要因为这个就产生顾虑, 他们都是 100% coverage 的.

@magicdawn 写的挺好的,对理解原理非常有帮助,继续加油

最近又多了一些 Promise 相关的帖子, 自顶 😂

@magicdawn 可以试试 https://github.com/ysmood/yaku ,几乎满足你的全部需求,模块化,无负担和污染,全部非 es 标准的都需要手动引用。 比如实现了个比 map 更抽象,性能更高的 concurrency 控制函数,可以试试 https://github.com/ysmood/yaku#alllimit-list 具体的一些细节都在文档里写了,希望能把向 promise.all 这些常用函数集成到 yaku,不知你有兴趣否?

@ysmood 我看 Yaku 里面已经有了不少方法了 ~ btw Promise.all 已经有语意了, 还是不要给这个方法加额外的参数吧, 会 confuse user, 换个名字更好… 😂

@magicdawn 但这个不是 Promise.all 是 utils.all,没有混淆的。并没有污染 Promise.all

@ysmood

拿 iterable, 去 yield promise … interesting

飞机上回去详细学习 From Noder

听说 v8 已经实现 async/await 可喜可贺啊…再顶…

很厉害 不错

回到顶部