Async: 使用 Async 设置事件处理程序

创建于 2016-10-25  ·  4评论  ·  资料来源: caolan/async

我在涉及事件处理程序的集成测试之一中使用 async 时遇到问题。 问题是在发出事件之前需要设置事件处理程序(引用异步提供的回调)。 但是,事件处理程序代码需要立即进行额外的回调。

这是一个显示问题的简化示例:

async.auto({
  // This needs to run first, but it will finish second
  event: [(next) => {
    emitter.once('awesome', next);
  }],

  // This needs to finish near the end
  checkResults: ['event', (results, next) => {
    assert(results.event.status == 200);
    assert(results.event.msg == 'cool');

    // Do other async stuff...
    somethingAsync(next);
  }],

  // This has to start second, but before the first one finishes
  emit: ['event', (results, next) => {
    event.emit('awesome', {msg: 'cool'}, next);
  }],

  checkEmit: ['emit', (results, next) => {
    // some sort of check that can be async
  },
], done);

event必须首先开始,但在emit发生之前不会结束。 emit需要等待event开始,而不是结束(也就是设置处理程序)。 因此这不会完成。

有没有办法用当前的异步库来做到这一点? (以干净的方式)

这是我想要的解决方案,假设这可以在异步中实现

async.auto({
  listen: [(next, done) => {
    client.on(done);
    return next();
  },

  ...
}, callback);

我可以使用并行,将发声器和侦听器(在测试中可以有多个)作为任务数组运行。 获取结果,并将检查作为第二部分。 但是,按顺序启动任务不需要技术上的并行(尽管可能会)。 此外,代码变得不那么平坦,尤其是在更复杂的设置中。

question

最有用的评论

我认为这是我见过的最疯狂的汽车用例:building_construction:

所有4条评论

@Saevon ,感谢您的提问!

一种快速、干净的方法是:

async.auto({
    // This needs to finish near the end
  checkResults: [(next) => {
    return next(null, (results, next) => {
      assert(results.event.status == 200);
      assert(results.event.msg == 'cool');

      // Do other async stuff...
      // somethingAsync(next);
    });
  }],

  // This needs to run first, but it will finish second
  event: ['checkResults', (handler, next) => {
    emitter.once('awesome', handler.checkResults);
    return next();
  }],

  // This has to start second, but before the first one finishes
  emit: ['event', (results, next) => {
    // Should this be emitter.emit instead of event.emit?
    event.emit('awesome', {msg: 'cool'}, next);
  }],

  checkEmit: ['emit', (results, next) => {
    // the results of `checkResults` will be in `results.emit`
    // as the handler on 'awesome' was passed the `next`
    // callback from `emit`

    // some sort of check that can be async
    yourChecks(next);
  }]
}, function done(err) {
    // everything finished running, unless `err` !== `null`
});

本质上,您只是交换了eventcheckResults依赖项,这实际上可能更简洁一些,因为event取决于checkResults的处理程序。 checkResults现在只是将处理程序传递给event

执行顺序为:
checkResults --> event --> emit --> handler (passed to event from checkResults) --> checkEmit --> done

让我知道是否有任何不清楚的地方。

是的,这解决了问题。 谢谢!

我认为这是我见过的最疯狂的汽车用例:building_construction:

同意。 通常异步回调和事件发射器不能很好地混合...

此页面是否有帮助?
0 / 5 - 0 等级