Node JS Express处理多个请求 [英] Node JS Express Handling multiple requests

查看:549
本文介绍了Node JS Express处理多个请求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


我有一个nodejs express服务器获取端点,然后调用其他耗时的API(例如大约2秒)。我用一个回调函数调用了这个函数,这样res.send被作为回调的一部分被触发。 res.send对象将打包一个对象,该对象将在执行这些耗时的API调用的结果之后创建。所以我的res.send只能在我有API调用的全部信息时发送。



一些代表性代码。

  someFunctionCall(params,callback)
{
//执行一些异步请求。
Promise.all([requestAsync1(params),requestAsync2(params)])。然后
{
//做一些操作
callback(response)数据来自promise


$ b app.get('/',function(req,res){
someFunctionCall(params,function(err,data ){
res.send(JSON.stringify(data))
}
}

我想要什么
我希望我的服务器能够处理其他并行传入的获取请求,而不会因其他函数中的REST API调用而被阻止。问题在于只有在承诺完成时才会发出回调,这些操作中的每一个都是异步的,但是我的线程会一直等到它们全部执行完毕,并且Node不会在不执行res.send的情况下接受下一个获取请求或者前一个请求的结尾。当我有多个请求进入时,每个请求都会一个接一个地执行。这成为一个问题。



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

解决方案

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



要查看你的代码实际上是阻塞的,你可以暂时添加一个简单的计时器,输出到控制台,如下所示:

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

当事件循环未被阻止时,每100ms相对时间戳。你显然不会在代码中留下这个代码来生产代码,但是当你的事件循环被阻塞时显示你可能是有用的。






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

  someFunctionCall(params,callback)
{
//执行一些异步请求。
Promise.all([requestAsync1(params),requestAsync2(params)])。然后
{
//做一些操作
callback(response)应该表达来自承诺的数据
}

}

像这样:

$ $ p $ someFunctionCall(params,callback)
{
//做一些异步请求。
Promise.all([requestAsync1(params),requestAsync2(params)])。then(function(response)
{
//做一些操作
callback(response)/ /回调给出了一些来自承诺的数据
}

});

但是,更好的设计是只返回promise并且不切换回普通的回调。除了允许调用者使用更灵活的承诺方案之外,您还可以吃可能发生在任一或异步操作中的错误。这是建议这样做的:

pre $ someFunctionCall(params){
//做一些异步请求。
return Promise.all([requestAsync1(params),requestAsync2(params)])then(function(results){
//进一步处理结果
//返回最终解析值承诺
返回someValue;
});
}

然后,调用者会使用这个:

  someFunctionCall(params).then(function(result){
//在此处理最终结果
})。catch(function err){
//在这里处理错误
});


What I Have: I have a nodejs express server get endpoint that in turn calls other APIs that are time consuming(say about 2 seconds). I have called this function with a callback such that the res.send is triggered as a part of the call back. The res.send object packs an object that will be created after the results from these time consuming API calls is performed. So my res.send can only be sent when I have the entire information from the API call.

Some representative code.

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))
   }
}

What I want I want my server to be able to handle other parallel incoming get requests without being blocked due to the REST api calls in the other function. But the problem is that the callback will only be issued when the promises are fulfilled,each of those operations are async, but my thread will wait till the execution of all of them. And Node does not accept the next get request without executing the res.send or the res.end of the previous request. This becomes an issues when I have multiple requests coming in, each one is executed one after another.

Note: I do not want to go with the cluster method, I just want to know if it is possible to this without it.

解决方案

You are apparently misunderstanding how node.js, asynchronous operations and promises work. Assuming your long running asynchronous operations are all properly written with asynchronous I/O, then neither your requestAsync1(params) or requestAsync2(params) calls are blocking. That means that while you are waiting for Promise.all() to call its .then() handler to signify that both of those asynchronous operations are complete, node.js is perfectly free to run any other events or incoming requests. Promises themselves do not block, so the node.js event system is free to process other events. So, you either don't have a blocking problem at all or if you actually do, it is not caused by what you asked about here.

To see if your code is actually blocking or not, you can temporarily add a simple timer that outputs to the console like this:

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

This will output a simple relative timestamp every 100ms when the event loop is not blocked. You would obviously not leave this in your code for production code, but it can be useful to show you when/if your event loop is blocked.


I do see an odd syntax issue in the code you included in your question. This code:

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
  }

}

should be expressed like this:

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
  }

});

But, an even better design would be to just return the promise and not switch back to a plain callback. Besides allowing the caller to use the more flexible promises scheme, you are also "eating" errors that may occur in either or your async operations. It's suggest this:

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;
    });
}

Then, then caller would use this like:

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

这篇关于Node JS Express处理多个请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆