在Electron中异步运行函数的正确方法是什么?

时间:2018-08-11 00:10:46

标签: javascript node.js electron

我想在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),就像上面的代码一样。在这里,似乎没有一种优雅的方法可以在工作程序开始运行之前传递启动参数。
  • 创建一个新的隐藏的BrowserWindow,如here所述。但是,我在其他地方找不到有关此方法的任何信息。

那么,有没有一种“正确”的,更直接的方法来实现我的目标?

1 个答案:

答案 0 :(得分:0)

  

实际上使用的是WebWorkers(或更小的TinyWorkers)

是的。这就是将代码移至其他线程的方式。

  

在这里,似乎没有一种优雅的方法可以在工作程序开始运行之前传递启动参数。

  1. 创建工作程序。除了监听postMessage事件外,它什么也没做。
  2. 使用带有起始参数的postMessage向其发送消息
  3. 工作程序中的事件侦听器获取消息并开始运行作业
  4. 完成后,postMessage从工作到主应用程序
  5. 主应用程序中的事件侦听器获取包含结果的消息