【问题标题】:NodeJs/expressjs : Run lengthy code in a callback [duplicate]Node Js / express js:回调中的运行长度代码[重复]
【发布时间】:2014-09-02 13:41:22
【问题描述】:

回调是异步的,这是否意味着如果我在回调中运行冗长的计算不会影响我的主线程?

例如:

function compute(req,res){    // this is called in an expressjs route.
    db.collection.find({'key':aString}).toArray(function(err, items) {
        for(var i=0;i<items.length;i++){      // items length may be in thousands.
            // Heavy/lengthy computation here, Which may take 5 seconds.
        }
        res.send("Done");
    });
}

因此,对数据库的调用是异步的。这是否意味着回调中的 for 循环不会阻塞主线程?

如果它是阻塞的,我怎样才能以异步方式执行这些事情?

【问题讨论】:

  • 回调你的主线程 - node.js 只有一个线程。每当您在 node.js 中花费超过几毫秒而不将其委托给另一个进程时,您应该会感觉很糟糕。 :)
  • 是的,我是这么想的,但是对此无能为力吗?其实我说5秒有点夸张。但是,有时需要进行一些处理。

标签: javascript multithreading node.js


【解决方案1】:

在大多数情况下,node.js 在单个线程中运行。但是,node.js 允许您进行调用以执行由单独线程处理的低级操作(文件读取、网络请求等)。因此,您的数据库调用很可能发生在单独的线程上。但是,当数据库调用返回时,我们返回主线程,您的代码将在主线程中运行(阻塞它)。

解决这个问题的方法是启动一个新线程。您可以使用cluster 来执行此操作。见:

http://nodejs.org/api/cluster.html

  • 您的主程序将调用数据库
  • 当数据库调用完成时,它将调用 fork() 并启动一个新线程,该线程运行 your-calculations.js 并向其发送带有任何输入数据的事件
  • your-calculations.js 会监听事件并在处理事件时进行必要的处理
  • your-calculations.js 将在完成处理后将事件发送回主线程(它可以发送回任何输出数据)
  • 如果主线程需要输出数据,可以监听your-calculations.js发出的事件

【讨论】:

  • 看起来像一个解决方案,我必须先阅读。谢谢你
【解决方案2】:

如果你做不到,或者不想使用线程,你可以用 setImmediates 拆分长计算。例如(在我的平板电脑上写得很快,所以可能很草率)

function compute(startIndex, max, array, partialResult, callback) {
   var done = false;
   var err = null;
   var stop = startIndex+100;  // or some reasonable amount of calcs...
   if (stop >= max) {
      stop = max;
      done = true;
   }

   // do calc from startIndex to stop, using partialResult as input
   if (done)
      callback(err, result);
   else 
      process.setImmediate ( go look this part up or I'll edit tomorrow)...
       But the idea is you call youself again with start += 100.
}

在每 100 次计算之间,节点将有时间处理其他请求、处理其他回调等。当然,如果它们触发另一个巨大的计算,最终事情会停止。

【讨论】:

  • 当然,我会检查 process.setImmediate。谢谢。
猜你喜欢
  • 1970-01-01
  • 2017-04-08
  • 2013-07-01
  • 1970-01-01
  • 2019-05-23
  • 2018-05-15
  • 2022-01-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多