【问题标题】:Event emitter between files not working with ES6 import/export and worker_thread不使用 ES6 导入/导出和 worker_thread 的文件之间的事件发射器
【发布时间】:2021-03-01 15:43:37
【问题描述】:

我有两个文件,第一个是 state.js,您可能会在下面看到:

import EventEmitter from "events";
import tasklist from 'tasklist';

export const stateManager = new EventEmitter();

//IIFE working every 10 seconds via cron task, from the file below
(async () => {
  const processes = await tasklist();
  const exist = processes.find(({imageName}) => imageName === 'process.exe');

  if (!!exist) {
    console.log(!!exist)
    stateManager.emit('state', 1);
  } else {
    console.log(!!exist)
    stateManager.emit('state', 0);
  }
})();

第二个是eventListener.js文件,无限运行。

//import stateManager from first file
import { stateManager } from "./src/controller.js";

/**
 * Here is part of the code
 * which starts the first file
 * as a Worker cron-task every 10 seconds
 * It doesn't block the thread.
 */
const bree = new Bree({
  logger: logger,
  jobs: []
});
bree.add({
  name: "state",
  interval: ms("10s")
})
bree.start();


// First listener
console.log('check');
stateManager.on('state', function firstListener(...args) {
  console.log('State updated', args);
});

启动eventListener.js 后,我在控制台中看到的输出如下:

check
false
State updated [ 0 ]
 [LOGGER]  21-03-01 18:03:67  info : Worker for job "state" online
false
 [LOGGER]  21-03-01 18:03:08  info : Worker for job "state" exited with code 0
 //every 10 second then =>
 [LOGGER]  21-03-01 18:13:69  info : Worker for job "state" online
false
 [LOGGER]  21-03-01 18:13:06  info : Worker for job "state" exited with code 0

或者如果我直接从另一个(第三个文件)而不是 state.js 导出 export const stateManager = new EventEmitter()

check
 [LOGGER]  21-03-01 18:03:23  info : Worker for job "state" online
false
 [LOGGER]  21-03-01 18:03:63  info : Worker for job "state" exited with code 0
 //every 10 second then =>
 [LOGGER]  21-03-01 18:13:23  info : Worker for job "state" online
false
 [LOGGER]  21-03-01 18:13:63  info : Worker for job "state" exited with code 0

所以任务工作正常,事件监听器永远不会结束,但不知何故,它不会对 state 事件做出反应,或者在开始时只反应一次。为什么会出现这样的问题?由于我在控制台中没有其他错误?

如果有帮助,我使用 bree.js 作为作业队列管理器,它实际上运行 cron 任务本身。

解决方案

我想我已经找到了问题的解决方案,但我无法理解原因本身。

就我而言,最好不要使用events 库,而是使用worker_threads,所以代码现在看起来像这样:

import { parentPort } from "worker_threads";
import tasklist from 'tasklist';

//IIFE working every 10 seconds via cron task, from the file below
(async () => {
  const processes = await tasklist();
  const exist = processes.find(({imageName}) => imageName === 'process.exe');
  if (parentPort) parentPort.postMessage({ state: !!exist })
})();

eventListener 接收端看起来像:

bree.on('worker created', (name) => {
  bree.workers[name].on('message', (message) => {
    console.log(message);  // Prints { state: !!exist }
  })
});

所以第一个文件中的消息已经成功传递。 但是,如果有人向我解释一下,为什么 events 库无法在不同作品之间传递消息,我会很高兴,即使 eventListener 已正确导出。

【问题讨论】:

  • async IIFE 在哪里每 10 秒完成一次?
  • 如果已被添加到作业队列,通过Bree
  • 为什么不在async 函数中添加一个try/catch。或调用后的catch 处理程序。
  • @MinusFour 它与try/catch 块本身无关。我发现它与worker_thread 库和Bree 的使用有关。所以我更新了我的问题。
  • 它不是每 10 秒打印一次 check 对我来说没有意义。这可能意味着Bree 正在做一些奇怪的事情。

标签: javascript node.js events eventemitter worker-thread


【解决方案1】:

Bree 基本上是启动一个新进程。你在那里得到的相当于做:

node eventListener.js

然后:

node state.js

每 10 秒。每 10 秒创建一个事件发射器,但没有附加侦听器,因为它位于您的 eventListener.js 文件中,没有运行,只是每 10 秒运行一次 state.js

Bree 对此可能有点矫枉过正,您可以只使用 setIntervalsetTimeout 循环。无论如何,这些都是async,而且你没有在 JS 方面做任何繁重的事情,所以你不应该阻塞太多。虽然如果你确实想使用工人,你的解决方案对我来说似乎没问题。直接与工人合作并放弃Bree 可能会更容易。

另一种选择是在单独的文件中设置 BreeeventListener。您只需运行另一个文件(它将每 10 秒运行一次您的所有程序)。

【讨论】:

    【解决方案2】:

    似乎我理解这种行为的原因,但我不确定这是 Bree 问题本身。

    只是不要将 IIFE 函数用作 Bree 的内置 cron-task。取而代之的是,使用文件中的 cron-task 。不管你怎么做,通过await sleep(time)和递归,或者通过节点调度模块本身。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-17
      • 2016-03-01
      • 2016-03-08
      • 2015-03-18
      • 2022-11-08
      相关资源
      最近更新 更多