如何在节点

时间:2019-02-12 06:22:21

标签: node.js express

我正在尝试扩展我的nodejs应用程序,以便它可以有效地同时处理多个请求。实现此目标的一种方法是通过代码优化,而我想知道如何使耗时的请求异步进行,诺言是唯一的方法吗?还是有另一种机制可以实现相同目标?

我已经将promise用于异步任务,但是据我所了解的promise,真正的异步部分是then和catch处理程序。当创建一个promise时,executor函数将由主线程执行,直到执行一些异步任务(setTimeout等)为止。

发送电子邮件的示例代码

   app.route('/api/contact/sendEmail')
       .post((req, res) =>{
           sendEmail(req).then( () =>{
               res.status(200);
               res.json({
                   sent: true
               });
           }).catch(emailError=> {
               //Custom error send bad request.
               if(emailError.code === 900) {
                   res.status(400);
                   res.json({
                       errorCode: emailError.code,
                       message: emailError.message
                   });
               }else {
                   res.status(500);
                   res.json({
                       errorCode: emailError.code
                   });
               }
           });
       });

不会阻塞线程发送响应,但是直到sendEmail没有到达实际的异步部分之前,主线程才会被阻塞

1 个答案:

答案 0 :(得分:2)

由于您没有提供有关正在使用的库/功能的详细信息,因此很难回答您的问题。 sendMail函数的来源,app是什么,以及在什么时候您认为某些内容受阻。

但是,通常,Node.JS中的代码始终在主线程中执行。这意味着,.js文件的每一行都位于主线程中,无论是否存在“异步”。

现在,要实际允许某些东西“异步”(即:在执行其他代码的同时执行 ),必须有一种方法可以将内容推到另一个线程中执行。这就是实际上在Node.JS中实际发生的情况。 Node.JS使用libuv / libev来实现事件循环来处理任务。它还具有许多后台/工作线程(默认情况下为4),这些线程执行阻止任务,例如网络或文件I / O。

但是,这是从Node.JS开发人员那里抽象出来的,因为它被嵌入在相应的 module 的实现中。例如,内置文件系统或网络模块将在后台线程中执行其任务(除非您使用-sync函数变体之一)。 如果您使用的是第三方模块,则取决于它是否用C / C ++编写并使用libuv来访问工作线程并进行后台处理。如果不是,那么您的第三方模块将在主线程上与您的代码相同地执行代码,如果是,则执行实际上是在后台线程中“异步”完成的。

也请参见以下非常有用的主题:How the single threaded non blocking IO model works in Node.js

这对您有什么帮助?
基本上,我想告诉您这一切都取决于您使用的功能/模块,以及它们是否被实现为后台操作(使用libuv)。最重要的是,您自己无法进行任何异步/同步操作,您必须使用该功能/模块实现的功能。

出于完整性考虑,我想提到Node.JS 11引入了worker_threads模块,该模块允许在javascript代码中使用线程,从而使您可以在后台线程中放置某些内容而不阻塞主线程。 。请注意,模块的稳定性仍然是“实验性的”。

边注
您真的确定您的代码阻塞了主线程吗?因为如前所述,网络IO始终发生在后台线程中,所以sendMail不太可能阻塞主线程(假设sendMail的工作是做网络IO)。 您是怎么发现它阻塞的?