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

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

我所知道的是,为了查询数据库等事情,我可以将一个事件产生到一个单独的进程(如mongodmysqld ),然后有一个callback来处理这个进程的结果。 很公平。

但是如果我想要在callback中完成一个沉重的计算。 在这个callback中的代码完全执行之前,是不是会阻止其他的请求呢? 例如,我想处理一个高分辨率的图像和代码,我已经在Javascript本身( no separate过程来做image processing)。

我想实施的方式就像

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

那个heavy_operation阻止节点接受这5秒的任何请求heavy_operation ? 还是我在想这样做的错误方式呢? 请指导,我是JS新手。

UPDATE

或者可以像我可以处理部分图像,并使事件循环回去采取其他callback,并返回到处理部分图像。 (比如优先事件)。

是的,它会阻止它,因为callback函数在主循环中执行。 它只是asynchronous调用不阻止循环的函数。 这是我的理解,如果你想image processingasynchronous执行,你将不得不使用一个单独的进程来做到这一点。

请注意,您可以编写自己的asynchronous过程来处理它。 开始你可以阅读如何编写Node.js的asynchronous函数的答案。

UPDATE

我如何在node.js中创build一个非阻塞的asynchronous函数? 也可能值得一读。 这个问题实际上是在我链接的另一个引用,但我想我会在这里包括它为简单起见。

不幸的是,我还没有足够的信誉点来评论Nick的答案,但是你看过Node的集群API吗? 目前它仍然是实验性的,但它可以让你产生多个线程。

当一个重要的计算在callback中完成时,事件循环将被阻塞直到计算完成。 这意味着callback会阻塞事件循环5秒钟。

我的解决scheme

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

没有发生器function

 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 

带有发生器function

 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生成器可以帮助运行繁重的计算function,当它仍然在计算时,会对事件循环进行控制。

要详细了解事件循环,请访问https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Statements/function*

https://davidwalsh.name/es6-generators