node.js中的异步调用

时间:2018-06-26 18:41:34

标签: node.js express

我对使用Express和中间件进行异步调用有一个基本的误解,我非常感谢能帮助理解它的人。

假设我们有以下代码:

var express = require('express')
var cookieParser = require('cookie-parser') 

var app = require('express')
var router = express.Router()

app.use(function timeLog (req, res, next) {
  req.requestTime = Date.now()
  next()
})

app .use(express.json());
app .use(express.urlencoded());
app.use(cookieParser())

router.post('/hello', function (req, res) {
  //write async to file
  res.send('bye')
})

现在,当客户端将该端点称为“ hello”时:

  1. 在应用程序级别定义的中间件称为异步吗?我知道它们会这样做(因为在文档中它们被称为“回调” ...因此基本上是在到达路由器之前:解析cookie,将json解析为req.body并添加req.requestTime将异步运行,然后路由至“ / hello的终点。

  2. 路由后,回调将异步运行吗?如果是,那么在这种情况下如何不保留请求?我看到响应已在回调主体中终止...这有什么意义? :(

有人请向我解释一下这个流程吗?

我将尝试通过上面的代码解释我如何理解“异步调用”:让很多用户尝试获得此终点。所有这些调用都添加到了调用堆栈中,然后由于这些回调是异步的,因此它们被移到事件队列/表中,并在调用堆栈为“空”之后进行处理。如果是这样,第一个用户将如何获得响应? requestTime完成异步,解析json完成异步,并在到达路由器时,回调完成异步...。因此,如果所有这些异步调用都位于事件Queue / table中,则第一个用户将获得代表。只有在调用栈为空后才能处理?我在这里想念什么?

谢谢。

2 个答案:

答案 0 :(得分:1)

中间件似乎不是自己异步的。换句话说,正如您在对另一个答案的评论中所说的那样,这不是将中间件/处理程序的expressjs“堆栈”中的每一层都强制放入JavaScript事件队列中的单独框架中。

如果您在next()中跟踪.use()函数,则很早就有几个setImmediate来处理“出口路由器”或“没有更多的层”,但是您会在处理程序堆栈上进入while循环。这发生在this point in the code附近。

因此,如果您所有的中间件都与本节类似,则所有中间件等都将在事件队列中的同一帧中发生:

app.use(function(req, res, next){
  console.log('synchronous layer');
  next();
});

下一个步骤是将next放入事件队列中的单独帧中,并有可能允许该进程处理可能排队的其他帧。

app.use(function(req, res, next){
  setImmediate(()=> {
    console.log('setImmediate puts this next() into a separate frame in the event queue');
    next();
  });
});

我无法想象这通常是一个问题。在中间件中可能要花费一些时间(数据库调用等)的大多数事情很可能都是异步发生的(将next放入事件队列的新帧中)。但这在添加中间件时值得考虑...

答案 1 :(得分:0)

所有这些中间件都使用延续传递样式。因此,基本上,它们可以异步运行。但是他们不必这样做。这取决于这些中间件是否正在执行某些IO。您可以看一下代码来检查函数的行为,但是至少这无关紧要。请记住,它们可以异步运行。