Добавяне на таймаут за обратно извикване в рамките на обещание и отхвърляне

Преобразувам функцията за излъчване на 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