文件之间的事件发射器不适用于 ES6 import/export 和 worker_thread
Event emitter between files not working with ES6 import/export and worker_thread
我有两个文件,第一个是 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
或者如果我从另一个(第三个文件)导出 export const stateManager = new EventEmitter()
而不是直接从 state.js
导出。
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
事件做出反应,或者只在开始时反应一次。为什么会出现这样的问题?由于我在控制台中没有其他错误?
If it helps, I use bree.js
as a job queue manager, which actually runs the cron-task itself.
解决方案
我想我已经找到了解决问题的方法,但我无法理解原因本身。
在我的例子中,最好不要使用 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
已正确导出,我也会很高兴。
Bree
基本上开始了一个新的进程。你得到的相当于做:
node eventListener.js
然后:
node state.js
每 10 秒一次。每 10 秒创建一个事件发射器,但没有附加侦听器,因为它在你的 eventListener.js
文件上,它不是 运行,只是每 10 秒 state.js
。
Bree 对此可能有点矫枉过正,您可以只使用 setInterval
或 setTimeout
循环。无论如何,这些都是 async
并且您没有在 JS 方面做任何繁重的事情,因此您不应该阻塞太多。虽然如果你确实想使用工人,你的解决方案对我来说似乎没问题。直接与工人合作并放弃 Bree
.
可能更容易
另一种选择是在单独的文件中设置 Bree
和 eventListener
。您只需 运行 那个其他文件(每 10 秒就会 运行 您的所有程序)。
似乎我理解这种行为的原因,但我不确定这是 Bree 问题本身。
只是不要将 IIFE 函数用作 Bree 的内置 cron 任务。取而代之的是,使用文件中的 cron-task。通过 await sleep(time)
和递归,或者通过 node-scheduler 模块本身,你将如何做并不重要。
我有两个文件,第一个是 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
或者如果我从另一个(第三个文件)导出 export const stateManager = new EventEmitter()
而不是直接从 state.js
导出。
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
事件做出反应,或者只在开始时反应一次。为什么会出现这样的问题?由于我在控制台中没有其他错误?
If it helps, I use
bree.js
as a job queue manager, which actually runs the cron-task itself.
解决方案
我想我已经找到了解决问题的方法,但我无法理解原因本身。
在我的例子中,最好不要使用 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
已正确导出,我也会很高兴。
Bree
基本上开始了一个新的进程。你得到的相当于做:
node eventListener.js
然后:
node state.js
每 10 秒一次。每 10 秒创建一个事件发射器,但没有附加侦听器,因为它在你的 eventListener.js
文件上,它不是 运行,只是每 10 秒 state.js
。
Bree 对此可能有点矫枉过正,您可以只使用 setInterval
或 setTimeout
循环。无论如何,这些都是 async
并且您没有在 JS 方面做任何繁重的事情,因此您不应该阻塞太多。虽然如果你确实想使用工人,你的解决方案对我来说似乎没问题。直接与工人合作并放弃 Bree
.
另一种选择是在单独的文件中设置 Bree
和 eventListener
。您只需 运行 那个其他文件(每 10 秒就会 运行 您的所有程序)。
似乎我理解这种行为的原因,但我不确定这是 Bree 问题本身。
只是不要将 IIFE 函数用作 Bree 的内置 cron 任务。取而代之的是,使用文件中的 cron-task。通过 await sleep(time)
和递归,或者通过 node-scheduler 模块本身,你将如何做并不重要。