Node JS Express处理多个请求

时间:2017-11-08 06:08:20

标签: node.js express asynchronous get

我有什么: 我有一个nodejs express服务器获取端点,后者又调用其他耗时的API(比如大约2秒)。我已经使用回调调用此函数,以便res.send作为回调的一部分被触发。 res.send对象打包一个对象,该对象将在执行这些耗时的API调用的结果后创建。所以我的res.send只能在我获得API调用的全部信息时发送。

一些有代表性的代码。

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请求而不会因为其他函数中的REST api调用而被阻止。但问题是回调只会在承诺完成时发出,每个操作都是异步的,但我的线程会等到所有这些操作都执行完毕。并且Node不接受下一个get请求而不执行res.send或前一个请求的res.end。当我有多个请求进入时,这就成了一个问题,每个请求都是一个接一个地执行。

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

1 个答案:

答案 0 :(得分:4)

你显然误解了node.js,异步操作和promises是如何工作的。假设长时间运行的异步操作都是使用异步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
  }

});

但是,更好的设计是返回承诺而不是切换回普通回调。除了允许调用者使用更灵活的promises方案之外,您还可以“吃掉”在异步操作或异步操作中可能出现的错误。这表明:

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