【问题标题】:Node.js Synchronous Library Code Blocking Async ExecutionNode.js 同步库代码阻塞异步执行
【发布时间】:2013-11-28 04:22:56
【问题描述】:

假设您有一个具有同步 API 的第 3 方库。自然,尝试以异步方式使用它会产生不良结果,因为您在尝试“并行”执行多项操作时会被阻止。

是否有任何通用模式允许我们以异步方式使用此类库?

考虑以下示例(为简洁起见,使用 NPM 中的 async 库):

var async = require('async');

function ts() {
  return new Date().getTime();
}

var startTs = ts();

process.on('exit', function() {
  console.log('Total Time: ~' + (ts() - startTs) + ' ms');
});

// This is a dummy function that simulates some 3rd-party synchronous code.
function vendorSyncCode() {
  var future = ts() + 50;  // ~50 ms in the future.

  while(ts() <= future) {} // Spin to simulate blocking work.
}

// My code that handles the workload and uses `vendorSyncCode`.
function myTaskRunner(task, callback) {
  // Do async stuff with `task`...

  vendorSyncCode(task);

  // Do more async stuff...

  callback();
}

// Dummy workload.
var work = (function() {
  var result = [];

  for(var i = 0; i < 100; ++i) result.push(i);

  return result;
})();

// Problem:
// -------
// The following two calls will take roughly the same amount of time to complete.
// In this case, ~6 seconds each.

async.each(work, myTaskRunner, function(err) {});

async.eachLimit(work, 10, myTaskRunner, function(err) {});

// Desired:
// --------
// The latter call with 10 "workers" should complete roughly an order of magnitude 
// faster than the former.

是我唯一的选择吗?

【问题讨论】:

    标签: node.js asynchronous blocking nonblocking synchronous


    【解决方案1】:

    是的,这是您唯一的选择。

    如果您需要使用 50 毫秒的 cpu 时间来做某事,并且需要执行 10 次,那么您将需要 500 毫秒的 cpu 时间来完成它。如果你希望它在少于 500 毫秒的挂钟时间内完成,你需要使用更多的 CPU。这意味着多个节点实例(或将工作推送到线程池的 C++ 插件)。如何获取多个实例取决于您的应用程序结构,使用 child_process.send() 将工作提供给子进程是一种方法,使用集群运行多个服务器是另一种方法。打破你的服务器是另一种方式。假设它是一个图像存储应用程序,并且大多数情况下处理请求的速度很快,除非有人要求将图像转换为另一种格式并且这会占用大量 CPU。您可以将图像处理部分推送到不同的应用程序中,并通过 REST API 访问它,让主应用程序服务器保持响应。

    如果您不担心执行请求需要 50 毫秒的 cpu 时间,而是担心无法将其他请求的处理与 cpu 密集型请求的处理交错处理,那么您可能会中断工作分成小块,并使用 setInterval() 安排下一个块。不过,这通常是一个可怕的黑客行为。最好重构应用程序。

    【讨论】:

      猜你喜欢
      • 2023-03-12
      • 1970-01-01
      • 2018-04-06
      • 2021-08-18
      • 2018-07-09
      • 1970-01-01
      • 2013-05-07
      • 1970-01-01
      • 2015-11-14
      相关资源
      最近更新 更多