javascript - node.js并行执行

标签 javascript node.js

我正在尝试学习 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/

相关文章:

javascript - 修复 jQuery 验证 + php 检查用户退出

node.js - Heroku 部署结束时出现错误 npm ERR! 404 未找到 : event-stream@3. 3.6

Node.js + Express + 样板 + jquery 模块不起作用

javascript - 卡在从第三帧抓取数据

javascript - 使用 JavaScript 对单个数组的多个属性进行分组

javascript - 如何从插槽访问组件数据?

javascript - 在 Ajax 中将输入发送到文件

javascript - 从 Angular 应用程序中的 Assets 下载文件

javascript - 悬停其他元素时保持背景颜色

node.js - 为什么我有两个版本的 npm