【问题标题】:Adding a timeout for a callback within a promise and rejecting在 Promise 中为回调添加超时并拒绝
【发布时间】:2015-04-03 00:28:59
【问题描述】:

我正在将 socket.io 的 emit 函数转换为这样的 Promise。

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 本身的参数。想法?

【问题讨论】:

  • 呃,节点风格的回调不坚持第一个参数是Error 实例? promisify 在这里应该很好用,当第一个参数为真时拒绝。
  • @Bergi 很高兴知道!但在规定的时间段内没有回调时拒绝仍然无济于事。
  • 还要注意 resolve 只接受一个参数,所以不确定你在用这个 apply 做什么。

标签: javascript node.js socket.io bluebird


【解决方案1】:

你当然可以使用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);
})

【讨论】:

    猜你喜欢
    • 2016-11-10
    • 1970-01-01
    • 2021-04-21
    • 1970-01-01
    • 2017-11-20
    • 1970-01-01
    • 2021-02-04
    • 1970-01-01
    • 2018-03-19
    相关资源
    最近更新 更多