如何在node.js中完成繁重的处理操作

时间:2013-03-10 00:17:43

标签: node.js image-processing

我有一个繁重的数据处理操作,我需要按照10-12的同步请求完成。我已经读过,对于更高级别的并发性,Node.js是一个很好的平台,它通过一个非阻塞事件循环来实现它。

我所知道的是,对于查询数据库这样的事情,我可以将事件产生到一个单独的进程(如mongodmysqld),然后有一个回调来处理结果从那个过程。很公平。

但是,如果我想在回调中完成大量计算,该怎么办?在完全执行该回调中的代码之前,它是否会阻止其他请求。例如,我想处理一个高分辨率的图像,我在Javascript本身的代码(no separate进程进行图像处理)。

我认为实施的方式就像

get_image_from_db(image_id, callback(imageBitMap) {
    heavy_operation(imageBitMap); // Can take 5 seconds.
});

heavy_operation是否会阻止节点接收5秒内的任何请求。或者我在想错误的方式来完成这样的任务。请指导,我是JS新手。

更新

或者就像我可以处理部分图像并使事件循环返回以接收其他回调并返回处理该部分图像。 (比如优先事件)。

3 个答案:

答案 0 :(得分:4)

是的,它会阻止它,因为回调函数在主循环中执行。只有异步调用的函数不会阻塞循环。我的理解是,如果您希望图像处理以异步方式执行,则必须使用单独的进程来执行此操作。

请注意,您可以编写自己的异步进程来处理它。首先,您可以阅读How to write asynchronous functions for Node.js的答案。

<强>更新

how do i create a non-blocking asynchronous function in node.js?也许值得一读。这个问题实际上是在我链接的另一个问题中引用的,但我认为为了简单起见,我将其包含在此处。

答案 1 :(得分:4)

不幸的是,我还没有足够的声望来评论尼克的答案,但你有没有看过Node's cluster API?它目前仍处于试验阶段,但它可以让你产生多个线程。

答案 2 :(得分:3)

当在回调中完成大量计算时,事件循环将被阻塞,直到计算完成。这意味着回调将阻止事件循环5秒钟。

我的解决方案

可以使用生成器函数来回退对事件循环的控制。我将使用一个运行3秒的while loop作为长时间运行的回调。

没有生成器功能

let start = Date.now();

setInterval(() => console.log('resumed'), 500);
function loop() {
    while ((Date.now() - start) < 3000) { //while the difference between Date.now() and start is less than 3 seconds
        console.log('blocked')
    }
}

loop();

输出结果为:

// blocked
// blocked
//
//  ... would not return to the event loop while the loop is running
//
// blocked
//...when the loop is over then the setInterval kicks in
// resumed
// resumed

使用生成器功能

let gen;
let start = Date.now();

setInterval(() => console.log('resumed'), 500);

function *loop() {
    while ((Date.now() - start) < 3000) { //while the difference between Date.now() and start is less than 3 seconds
        console.log(yield output())
    }
}

function output() {
    setTimeout(() => gen.next('blocked'), 500)
}

gen = loop();
gen.next();

输出结果为:

// resumed
// blocked
//...returns control back to the event loop while though the loop is still running
// resumed
// blocked
//...end of the loop
// resumed
// resumed
// resumed

使用javascript生成器可以帮助运行繁重的计算功能,这些功能可以在事件循环计算时产生后退控制。

了解有关事件循环访问的更多信息 https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Statements/function*

https://davidwalsh.name/es6-generators