【发布时间】:2018-08-11 18:39:59
【问题描述】:
我想在 Electron 中异步运行一个简单的函数,所以它不会阻塞我的渲染线程。所以,像这样的东西(非常粗略)(在render.js 内):
var max = 42; // Somehow needs to be passed to the function
function foo() {
for (var i = 0; i < max; i++) {
// Do something...
// ... and tell the render thread about it.
}
}
foo(); // Should run asynchronously
有两个要求:
- 我必须将参数传递给函数(这里:
max)。这些不仅可以是整数,还可以是对象。该函数在收到这些参数之前不得运行。 - 在运行时,必须有一个到渲染线程的通信通道。例如,定期报告从
for循环一直到 UI 的进度,或者在渲染线程中的事件触发时中止函数。
这是一个更具体的最小工作(或者更确切地说,不工作)示例。目的是将串行命令发送到物理设备,在该物理设备上,探针应移动到指定网格中的所有位置。所以我需要两个循环(一个用于 x,一个用于 y)。循环体将包含在电机移动之前阻塞的功能,然后必须将来自该位置的测量值传达回 UI。此外,在循环开始运行之前,必须知道有关网格的规范(因此我要求传递参数。)
var Parameters = {x_length: 50, y_length: 50};
//These functions interact with a serial device and block until it is done with its task
function moveTo(x, y) {/*...*/};
function measure() {/*...*/};
//This function should eventually be executed asynchronously
function scan() {
for (var x = 0; x < Parameters.x_length; x++) {
for (var y = 0; y < Parameters.y_length; y++) {
moveTo(x, y);
var result = measure();
// Here, we need to tell the render thread about results. I used
// postMessage (WebWorker syntax) as a placeholder.
postMessage({
position: {x: x, y: y},
data: result
});
}
}
}
// This is what will be actually called, e. g. when the user clicks a
// button.
function scan_async() {
//Again, I used WebWorker (or rather, TinyWorker) syntax as a placeholder.
var scan_worker = new Worker(scan);
scan_worker.onmessage = function (msg) {
console.log(msg.data);
};
}
经过数小时非常令人沮丧的谷歌搜索后,我找到了很多方法,但没有一种方法似乎是“确定”的方法,或者不符合上述几点,或者对于我想要的东西来说似乎很复杂去实现。
到目前为止我发现了什么:
- 实际上使用 WebWorkers(或者更确切地说是 TinyWorkers,https://github.com/avoidwork/tiny-worker),就像上面的代码一样。在这里,似乎没有优雅的方法可以在 worker 开始运行之前传递启动参数。
- 创建一个新的隐藏
BrowserWindow,如here 所述。但是,我在其他地方找不到有关此方法的任何信息。
那么,有没有一种“正确”、更直接的方式来实现我的目标?
【问题讨论】:
-
不知何故使用节点的异步 - 这不是节点的异步。这是每个人的异步,它是 ES2017。问题不够具体。请解释您的实际问题,而不仅仅是 foo 抽象。解决方案取决于它。 做某事 - 这是什么?真的只有 42 次迭代吗? 在运行时,必须有一个到渲染线程的通信通道 - 这没有显示。请向stackoverflow.com/help/mcve 提供您当前的尝试,清楚地表明您真正想要做什么。
-
对不起,如果我太含糊了。我希望现在好多了:)
-
将长时间运行的代码放入 Promise 中不会将该代码推送到不同的线程。
async帮不了你。 -
好的,我将删除那个项目符号。
-
@jmb
@必须用于参与者接收通知。是的,这更好,但重要的细节尚不清楚。测量是如何工作的,为什么它会阻塞?这很重要。它使用的功能可能在 web worker 中不可用。通常,您在浏览器中为网络工作者提供 CPU 密集型或阻塞代码 - 或者如果它是 Node.js 则将其分叉。您仍然可以在需要时使用 async/await。
标签: javascript node.js electron