Node JS Express处理多个请求



我所拥有的:我有一个nodejs express服务器get端点,它反过来调用其他耗时的API(比如大约2秒)。我用回调调用了这个函数,这样res.send就会作为回调的一部分被触发。res.send对象打包一个对象,该对象将在执行这些耗时的API调用的结果后创建。因此,只有当我从API调用中获得全部信息时,才能发送res.send。

一些有代表性的代码。

someFunctionCall(params, callback)
{
// do some asyncronous requests.
Promise.all([requestAsync1(params),requestAsync2(params)]).then
{
// do some operations
callback(response) // callback given with some data from the promise
}
}
app.get('/',function(req, res){
someFunctionCall(params, function(err, data){
res.send(JSON.stringify(data))
}
}

我想要的我希望我的服务器能够处理其他并行传入的get请求,而不会因为其他函数中的RESTapi调用而被阻止。但问题是,只有在承诺实现时才会发出回调,每个操作都是异步的,但我的线程会等到所有操作执行完毕。如果不执行上一个请求的res.send或res.end,Node将不接受下一个get请求。当我收到多个请求,每个请求都被一个接一个地执行时,这就成了一个问题。

注意:我不想使用集群方法,我只想知道如果没有它,这是否可能。

您显然误解了node.js、异步操作和promise的工作方式。假设长时间运行的异步操作都是用异步I/O正确编写的,那么requestAsync1(params)requestAsync2(params)调用都没有阻塞。这意味着,当您等待Promise.all()调用其.then()处理程序以表示这两个异步操作都已完成时,node.js完全可以自由运行任何其他事件或传入请求。Promise本身不会阻塞,因此node.js事件系统可以自由处理其他事件。所以,你要么根本没有阻塞问题,要么如果你真的有,这不是你在这里问的问题造成的。

要查看您的代码是否真的被阻塞,您可以临时添加一个简单的计时器,该计时器输出到控制台,如下所示:

let startTime;
setInterval(function() {
if (!startTime) {
startTime = Date.now();
}
console.log((Date.now() - startTime) / 1000);
}, 100)

当事件循环未被阻止时,这将每100ms输出一个简单的相对时间戳。很明显,您不会将其保留在生产代码的代码中,但当/如果您的事件循环被阻止时,向您显示它可能会很有用。


在您的问题中包含的代码中,我确实看到了一个奇怪的语法问题。此代码:

someFunctionCall(params, callback)
{
// do some asyncronous requests.
Promise.all([requestAsync1(params),requestAsync2(params)]).then
{
// do some operations
callback(response) // callback given with some data from the promise
}
}

应该这样表达:

someFunctionCall(params, callback)
{
// do some asyncronous requests.
Promise.all([requestAsync1(params),requestAsync2(params)]).then(function(response)
{
// do some operations
callback(response) // callback given with some data from the promise
}
});

但是,一个更好的设计是只返回承诺,而不是切换回简单的回调。除了允许调用者使用更灵活的promise方案外,您还"吃掉"了异步操作中可能发生的错误。建议如下:

someFunctionCall(params) {
// do some asyncronous requests.
return Promise.all([requestAsync1(params),requestAsync2(params)]).then(function(results) {
// further processing of results
// return final resolved value of the promise
return someValue;
});
}

然后,调用方会像这样使用:

someFunctionCall(params).then(function(result) {
// process final result here
}).catch(function(err) {
// handle error here
});

最新更新