我正在尝试学习 node.js 中的并行执行。我写了下面的示例代码。但是,输出是串行的。首先打印 0..99,然后打印 100..200。
我理解这是因为 node.js 本质上是单线程的,并且在循环内部,线程被 for 循环捕获。
我想了解的是这种flow.parallel
结构在什么情况下有用?无论如何,对 I/O 或数据库的任何请求在 node.js 中都是异步的。那我们为什么需要 flow.parallel
呢?
var flow = require('nimble');
flow.parallel([
function a(callback)
{
for(var i=0;i<100;++i)
{
console.log(i);
}
callback();
},
function b(callback)
{
for (var i=100;i<200;++i)
{
console.log(i);
}
callback();
}
]);
最佳答案
在大多数情况下,使用像这样的并行流程,您不会在 for 循环中打印一堆数字(这恰好会阻止执行)。当您注册您的函数时,它们的注册顺序与您在传递给 parallel
的数组中定义它们的顺序相同。在上面的例子中,首先是 function a
,然后是 function b
。因此,Node 的事件循环将首先调用 a()
,然后在未公开的时间调用 b()
。因为我们知道那些 for 循环是阻塞的,并且 Node 在单个线程中运行,所以它必须在 a()
中完成整个 for 循环,并最终在 Node 的事件循环开始控制它之前返回同样,b()
在队列中等待类似的处理。
为什么并行流程控制结构有用?按照设计,您不应该在 Node 内执行阻塞操作(请参阅您的示例)。 a()
消耗整个线程,然后 b()
将在其他任何事情发生之前消耗整个线程。
a() b()
|
|
|
|
RET
|
|
|
|
RET
现在,假设您正在开发一个网络应用程序,用户可以在其中注册并同时上传图片。您的用户注册可能有这样的代码:
var newUser = {
username: 'bob',
password: '...',
email: 'bob@example.com',
picture: '20140806-210743.jpg'
}
var file = path.join(img.IMG_STORE_DIR, newUser.picture);
flow.parallel([
function processImage(callback) {
img.process(function (err) {
if (err) return callback(err);
img.save(file, function (err) {
return callback(err); // err should be falsey if everything was good
})
});
},
function dbInsert(callback) {
db.doQuery('insert', newUser, function (err, id) {
return callback(err);
});
}
], function () {
// send the results to the user now to let them know they are all registered!
});
这里的内部函数是非阻塞的,并且都调用处理或网络负载操作。但是,它们彼此相当独立。您不需要一个完成另一个就可以开始。在我们看不到代码的函数中,它们使用了更多带有函数回调的异步调用,每个调用都将另一个项目排入队列以供 Node 处理。 Node 将尝试清除队列,在 CPU 周期之间平均分配工作负载。
我们希望现在正在发生这样的事情:
a = processImage
b = dbInsert
a() b()
|
|
|
|
|
|
|
RET |
RET
如果我们将它们串联起来,即您必须等待图像在数据库插入之前完全处理完毕,您必须等待很多时间。如果您的系统上的 IO 真的很高, Node 将在操作系统上等待。相比之下,理论上,使用并行将允许慢速操作让位于更快的操作。
如果 Node 自己做,为什么我们真的需要它?关键在于您省略的第二个参数。
nimble.parallel([a,b], function () {
// both functions have now returned and called-back.
});
您现在可以看到这两个任务何时完成, Node 默认情况下不会执行此操作,因此拥有它可能是一件非常有用的事情。
关于javascript - node.js并行执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25173808/