一个在 co 中,控制 timeout 的库:ko-timeout
发布于 8 年前 作者 alsotang 4813 次浏览 来自 分享

https://github.com/alsotang/ko-timeout

ko-timeout

Build Status

usage

timeout(gen, ms)

gen - a genarator function

ms - millisecond. can use ‘3s’ or ‘200ms’, which https://www.npmjs.com/package/ms support

example

should timeout

try {
  yield timeout(function * () {
    yield sleep(50)
  }, 20)
} catch (e) {
  e.message.should.eql('timeout: exceed 20ms')
}

should get return value

var value = yield timeout(function * () {
  yield sleep(10)
  return 30;
}, 20)

value.should.eql(30)

license

MIT

10 回复

是学习promise用法和如何封装npm的好例子

蓝鸟大法好 http://bluebirdjs.com/docs/api/timeout.html

GLOBAL.Promise  = require('bluebird');

co(function* (){
  try{
    yield Promise.delay(50).timeout(20);
  } catch (e){
   assert(e instanceof Promise.TimeoutError);
  }
})

https://github.com/petkaantonov/bluebird/blob/master/src%2Ftimers.js#L58

Promise.prototype.then() // 不传 onfulfilled & onrejected 是返回它自己么

规范说的ignore, Taxi returns new Taxi, https://github.com/William17/taxi/blob/master/taxi.js#L165 先用 TimeoutError reject掉, 后续resolve不能继续执行.

@magicdawn 这地方为什么空调用,我看不懂。。

@alsotang 返回一个新的 Promise ?

@magicdawn 感觉是的,但为什么要这么做,难道跟执行顺序有关?

@magicdawn
不好意思,Taxi里面漏了2个注释,已经补上,分别是下面的 2.2.7.3 和 2.2.7.4

规范规定then必须返回一个promise , 实现的时候在某些情况可以返回同一个promise,见 3.3

2.2.7 then must return a promise [3.3]. promise2 = promise1.then(onFulfilled, onRejected);
2.2.7.3 If onFulfilled is not a function and promise1 is fulfilled, promise2 must be fulfilled with the same value as promise1.
2.2.7.4 If onRejected is not a function and promise1 is rejected, promise2 must be rejected with the same reason as promise1.

3.3 Implementations may allow promise2 === promise1, provided the implementation meets all requirements. Each implementation should document whether it can produce promise2 === promise1 and under what conditions.

因为 Promise-instance.resolve 不是API的一部分, 如果从规范去了解API, 去实现 delay, timeout 的话, 只能是 new Promise 但是库的话, 有私有 API , 去 promise.resolve(x), 可以新建 Promise , 也可以直接在 this 上操作 ~ then() 是返回 new Promise 还是 this无所谓了.

'use strict';

Promise.prototype.timeout = function(ms, msg) {
  return new Promise((resolve, reject) => {
    let handler = setTimeout(() => {
      var e = new Error(msg);
      e.type = 'TimeoutError';
      reject(e);
    }, ms);

    this
      .then(x => {
        clearTimeout(handler);
        resolve(x);
      })
      .catch(e => {
        clearTimeout(handler);
        reject(e);
      });
  });
};

Promise.prototype.delay = function(ms) {
  return new Promise((resolve, reject) => {
    this
      .then(x => {
        setTimeout(() => {
          resolve(x);
        }, ms);
      })
      .catch(e => {
        setTimeout(() => {
          reject(e);
        }, ms);
      });
  });

};

Promise
  .resolve(10)
  .delay(50)
  .timeout(30, '30 ms exceed')
  .catch(e => console.error(e.stack || e));

不好意思, 将你的 co 库广告贴变成了 Promise 学习贴 :joy:

回到顶部