(找到解决方案)
我想用代码示例开始我的问题:
var express = require('express');
var customModule = require('./custom-module');
var app = express();
// Page A
app.get('/a', function(req, res) {
res.type('text/plain');
customModule.doHeavyOperation(25, function(result) {
res.send('Page A, number = ' + result);
});
});
// Page B
app.get('/b', function(req, res) {
res.type('text/plain');
res.send('Page B');
});
app.listen(8082);
对于页面 A,调用 doHeavyOperation() 执行一些操作,完成后,它运行我的回调,向用户发送一些信息。
cutsom-module.js:
exports.doHeavyOperation = function(number, callback) {
for (var i=0; i<2000000000; i++) {
number++;
}
callback(number);
};
对于 doHeavyOperation() ,执行其逻辑并调用我的回调需要约 5 秒的时间。当我在浏览器中打开两个页面: localhost:8082/a 和 localhost:8082/b 时,第二个页面需要等待第一个页面加载。这意味着请求不是同时处理的。
除了 doHeavyOperation 之外,还可以有任何其他函数在我的客户端尝试使用我的 Web 应用程序时卡住我的客户端。例如,我可能想要处理用户上传的一些大图像,对其应用一些过滤器等。这可能需要 1-3 秒。所以如果有100人同时使用我的网站,就会造成很大的问题。
例如,Apache + PHP 就很好地处理了这种情况。当脚本 a.php 执行一些操作时,脚本 b.php 可以毫无问题地加载。
如何在 Node.js + Express 中实现此行为?
======================================================================================
根据 kamituel 的评论,我的决定是生成新进程来执行“繁重”计算并将结果返回给父进程。现在应用程序可以按我想要的方式工作。
我修改了我的代码:
var express = require('express');
var app = express();
// Page A
app.get('/a', function(req, res) {
// Creating child process
var child = require('child_process').fork('custom-module.js');
// Sending value
child.send(25);
// Receiving result
child.on('message', function(result) {
res.type('text/plain');
res.send('Page A, number = ' + result);
});
});
// Page B
app.get('/b', function(req, res) {
res.type('text/plain');
res.send('Page B');
});
app.listen(8082);
自定义模块.js:
function doHeavyOperation(number, callback) {
for (var i=0; i<2000000000; i++) {
number++;
}
callback(number);
};
process.on('message', function(number) {
doHeavyOperation(number, function(result) {
process.send(result);
});
});
有关 child_process 的更多信息 here .
最佳答案
Javascript(Node.js 也是如此)使用一个主线程来处理(几乎)您编写的所有 JS 代码。这意味着如果您有一些长时间运行的任务(例如示例中的巨大循环),则该任务将阻止其他代码(即回调)的执行。
对此你能做什么?
- 将循环分成更小的部分,并偶尔产生控制(即使用 setTimeout/nextTick 或类似的)。 IE。您可以从 0 迭代到 1000,然后在下一个刻度上执行接下来的 1000 次循环迭代,依此类推。
- 生成一个新进程并在那里处理繁重的任务。由于新进程将位于 Node.js 本身之外,因此不会阻止它。
关于javascript - Node.js + Express 应用程序中的并发如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26547431/