2015-04-02 7 views
0

Я преобразую функцию испускания socket.io в такое обещание.Добавление таймаута для обратного вызова в рамках обещания и отклонения

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 выше никогда не будет resolve или reject ничего. Так что мне нужен тайм-аут этого callback, если ничего не возвращается в течение отведенного периода времени, тогда он будет reject(new Error("timeout")). Дело в том, что я не знаю, как это сделать. В идеале я могу установить seconds, чтобы подождать в пределах функции выше, или, если знаете, что нет обратного вызова для данного события, я хотел бы resolve, поэтому в идеале это параметр emitAsync. Мысли?

+0

Мм, обратные вызовы узел стиля не настаиваю на первый аргумент будучи Экземпляр «Ошибка»? 'promisify' должен хорошо работать здесь, отвергая, когда первый аргумент правдив. – Bergi

+0

@ Bergi Полезно знать! но по-прежнему не помогает отклонять, когда нет обратного вызова в течение отведенного периода времени. – ThomasReggi

+0

Также обратите внимание, что 'resolve' принимает только один аргумент, поэтому не уверен, что вы делаете с этим' apply'. – Bergi

ответ

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); 
})