Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/42.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何使用超时和侦听器创建未来_Javascript_Node.js_Events_Asynchronous_Meteor - Fatal编程技术网

Javascript 如何使用超时和侦听器创建未来

Javascript 如何使用超时和侦听器创建未来,javascript,node.js,events,asynchronous,meteor,Javascript,Node.js,Events,Asynchronous,Meteor,我正在尝试创建一个具有未来的函数。在此函数中,它将等待结束或错误事件。如果x秒内没有写入数据,它将返回一个错误。这是我写的 Cylon.execute = function (subroutine, timeout=60000) { let future = new Future(); let done = future.resolver(); let timeoutId = Meteor.setTimeout(function () { done(new Meteor.E

我正在尝试创建一个具有未来的函数。在此函数中,它将等待
结束
错误
事件。如果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返回时,事件侦听器仍处于绑定状态
  • 由于超时,未来可能会返回多次

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

首先,我建议您执行此操作。一次,而不是此操作。启用此选项后,您将只触发事件处理程序一次。 没有必要多次触发它

我也建议你这样做

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将防止对同一事件进行多次处理,但如果触发了不同的事件,您仍将收到多次调用,因此,您还必须像我最初写的那样进行事件侦听器清理。我遇到的另一个问题是处理超时。我在fibers API中找不到任何指定“从一系列期货中只返回一个期货”(以先返回的为准)的内容。我认为问题在于,您在那里有多个setTimeout,因此即使取消一个,另一个仍然有效。因此,在创建新的setTimeout之前,必须清除任何setTimeout。您在开始时有1个setTimeout,但与第一次打开(“数据”)时相比,您执行了另一个setTimeout并松开了first timeoutID,并且您没有取消该超时。所以你已经触发了它,虽然你并不真的想。