2016-08-22 128 views
0

说,有提供了一个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()来包含超时?

+0

将超时作为参数传递给connect函数。 –

+0

如前所述,我有兴趣解决这个问题,我无法控制'connect()'。 –

回答

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接口没有记录。

+0

我无法控制'connect()',它无法更改。 –

+0

怎么样?这是实例化超时的自然地点,所以也许你应该从任何可以改变它的人那里请求这个功能。 – Bergi

+0

我发布的仅仅是一个我希望很容易理解的例子。我在这种情况下实际上有一个'shell()'命令。它在'shell'('echo 1')'(短命)和'shell('true; echo 1; sleep 1; done')'(长命)'风格中被使用。虽然我想确保连接在最后关闭,但处理可能需要多长时间没有上限。因此,直接在'shell()'中设置超时是没有意义的,因为在某些情况下,我绝对不想超时,并且传递'Infinity'似乎不是很习惯。 –