Добавление тайм-аута для обратного вызова в обещании и отклонение

Я преобразовываю функцию emit 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 не возвращает сигнатуру обратного вызова в стиле узла. Первый аргумент не может быть объектом ошибки. Таким образом, план состоит в том, чтобы передать строковое сообщение об ошибке, приведенное выше обещание будет отклонить, если первый аргумент равен truthy. Это все прекрасно и денди, вот в чем проблема.

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


person ThomasReggi    schedule 02.04.2015    source источник
comment
Э-э, обратные вызовы в стиле узла не настаивают на том, чтобы первый аргумент был экземпляром Error? promisify здесь должно хорошо работать, отклоняя, когда первый аргумент верен.   -  person Bergi    schedule 02.04.2015
comment
@Bergi Полезно знать! но все же не помогает с отклонением, когда нет обратного вызова в течение выделенного периода времени.   -  person ThomasReggi    schedule 02.04.2015
comment
Также обратите внимание, что resolve принимает только один аргумент, поэтому не уверен, что вы делаете с этим apply.   -  person Bergi    schedule 02.04.2015


Ответы (1)


Вы можете просто использовать Bluebird timeout метод конечно…

Решением более низкого уровня было бы использование 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);
})
person Bergi    schedule 02.04.2015