2015-04-02 69 views
0

我將socket.io的emit函數轉換爲這樣的承諾。在承諾中添加回調超時並拒絕

var io = require("socket.io-client") 
var Promise = require("bluebird") 
var _ = require("underscore") 

io.emitAsync = function(event, payload){ 
    return new Promise(function (resolve, reject) { 
    return io.emit(event, payload, function(){ 
     var args = _.toArray(arguments) 
     if(args[0]) reject(new Error(args[0])) 
     resolve.apply(null, args) 
    }) 
    }) 
} 

我不能使用promiseify因爲io.emit回調不返回節點式的回調簽名。 The first argument can't be an error object.所以計劃是傳遞一個字符串錯誤信息,如果第一個參數是truthy,上面的承諾將會被拒絕。這一切都很好,這是問題所在。

如果你不回你的socket.on那麼這個承諾變成callback上面永遠不會resolvereject什麼。所以我需要的是這個callback超時,如果沒有在指定的時間內回來,那麼它會reject(new Error("timeout"))。事情是我不知道如何做到這一點。理想情況下,我可以設置seconds在上面的函數中等待,或者如果知道沒有給定事件的回調,我想resolve,所以理想情況下它是emitAsync本身的參數。思考?

+0

呃,節點式的回調不上的第一個參數是一個堅持'錯誤'實例? 'promisify'應該在這裏工作得很好,拒絕第一個參數是truthy的時候。 – Bergi 2015-04-02 16:23:33

+0

@Bergi很高興知道!但仍然無助於在分配的一段時間內沒有回撥時拒絕。 – ThomasReggi 2015-04-02 16:25:41

+0

另請注意,'resolve'只有一個參數,所以不知道你在用這個'apply'來做什麼。 – Bergi 2015-04-02 16:30:16

回答

3

你可以只使用過程中的Bluebird timeout method ...

更低級別的解決方案是使用setTimeout

new Promise(function (resolve, reject) { 
    io.emit(event, payload, function(err){ 
    if(err) reject(new Error(err)) 
    resolve(_.toArray(arguments).slice(1)); 
    }) 
    setTimeout(function(){ 
    reject(new Error("timeout")); 
    }, seconds*1000); 
})