处置器超时

时间:2016-08-22 19:26:51

标签: node.js promise bluebird

假设有一个提供connect()方法的库,由于您连接的服务器有时会花费很长时间:

var stream = require('stream')

function connect() {
  return Promise.delay(Math.random() * 60000)
    .return(stream.PassThrough())
    .disposer(function(conn) { conn.end() })
}

请注意disposer()的使用,以确保在使用后关闭连接。

现在,您需要connect(),但如果无法建立连接,则会在5秒内超时。

所以你试试:

Promise.using(connect().timeout(5000), function(conn) {
  console.log('Hello world')
})

由于connect()返回Disposer

,这显然不起作用

哦,我只是将超时置于使用块内,你可能天真地想。好吧,这也行不通,因为我们只有在连接建立后才进入块。

所以最后你试试:

Promise.using(connect(), function(conn) {
  console.log('Hello world')
})
.timeout(5000)

这当然有效。但是,我们不幸有一个简单的console.log是我们的任务。相反,它看起来更像是:

Promise.using(connect(), function(conn) {
  // Do an awfully long task that takes 2 minutes
})
.timeout(5000)

现在超时再次变得无法使用,因为非常长的任务自然会花费很长时间,导致每次都触发超时。

有没有办法以某种惯用的方式写这个,不需要更改connect()来包含超时?

1 个答案:

答案 0 :(得分:1)

你应该可以使用

function connect(timeout) {
  return Promise.delay(Math.random() * 60000)
    .return(stream.PassThrough())
    .timeout(timeout)
    .disposer(function(conn) { conn.end() })
}

Promise.using(connect(5000), …)

如果您无法更改connect,则可以应用以下黑客攻击:

var connection = connect();
connection = connection.promise().timeout(5000).disposer(connection.data());
Promise.using(connection, …);

请注意Disposer接口未记录。