【问题标题】:How to create future with timeout and listeners如何使用超时和侦听器创建未来
【发布时间】:2015-12-23 10:39:49
【问题描述】:

我正在尝试创建一个具有未来的功能。在此函数中,它将等待EndError 事件。如果 x 秒内没有写入数据,则会返回错误。这是我写的。

Cylon.execute = function (subroutine, timeout=60000) {
  let future = new Future();
  let done = future.resolver();

  let timeoutId = Meteor.setTimeout(function () {
    done(new Meteor.Error('CylonTimeout'));
  });
  this._messages.on('data', () => {
    timeoutId = Meteor.setTimeout(function () {
      done(new Meteor.Error('CylonTimeout'));
    });
  });
  this.on('End', () => {
    Meteor.clearTimeout(timeoutId);
    done(null, subroutine);
  })
  this.on('Error', (err) => {
    Meteor.clearTimeout(timeoutId)
    done(err, null)
  });
  this._commands.write(`Execute #${subroutine}\r`, 'utf8');
  return future.wait();
}

我遇到了一些问题。

  • future 返回时,仍绑定事件监听器
  • future 会因为超时而返回多次

期货通常如何处理?有什么方法可以清理这些事件吗?

【问题讨论】:

    标签: javascript node.js events asynchronous meteor


    【解决方案1】:

    首先,我建议您执行 this.once 而不是 this.on,这样您只会触发一次事件处理程序。 无需多次触发。

    我也建议你这样做

    var self = this;
    done = function (err, result) {
      //remove all listeners
      self.removeListener('Error', handler);
      //.... and so on....
    
      future.resolver()(err, result);//call actual done
    }
    

    这将防止 done 被多次调用并删除事件侦听器。

    【讨论】:

    • once 会阻止对同一事件的多次处理,但如果触发了不同的事件,您仍然会收到多次调用,因此您还必须按照我最初写的那样进行事件侦听器清理。
    • 我遇到的唯一其他问题是处理超时。我在纤维 API 中找不到任何指定“从一系列期货中仅返回一个未来”(以先返回者为准)
    • 我认为问题在于你有多个 setTimeout ,所以即使你取消一个,另一个仍然存在。因此,您必须在创建新的 setTimeout 之前清理任何 setTimeout。您在开始时有 1 个 setTimeout,但在第一个 on('data') 上,您执行另一个 setTimeout 并松开第一个 timeoutID 并且您没有取消该超时。所以....虽然你真的不想触发,但你已经触发了它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-12
    • 2016-12-14
    • 2023-03-28
    • 1970-01-01
    • 2021-01-05
    • 1970-01-01
    相关资源
    最近更新 更多