Expressjs 路由请求和响应是异步的?

Posted

技术标签:

【中文标题】Expressjs 路由请求和响应是异步的?【英文标题】:Expressjs routes request & responses are async? 【发布时间】:2015-12-24 10:55:31 【问题描述】:

我有这个疑问,确实不是问题,但我想知道我处理请求和响应的实际结构是否是非阻塞的。

我的一些代码如下所示:

get: (req, res) ->
    permission = req.user.username

    if not permission
      return res.json new Unauthorized("#req.user.username no tiene permisos")

    Client.find()
      .exec (err, clients) ->
        if err then res.json new Internal(err.message, err.stack)
        if not clients then res.json new NotFound('No encontrado')

        res.json new Ok(clients, 'OK')

当然是在路由器存档中处理的,但我不知道我的代码什么时候是异步的,什么时候不是。

那么,如果这是一个异步非阻塞代码,有人可以解释一下吗?如果不是,请提供一些文档或库?我尝试使用promisejs,但它在执行过程中引发了一些错误(我认为那是因为我很菜鸟)。

就是这样,提前谢谢!

【问题讨论】:

您实际上可以通过在 exec 回调中添加 console.log('found') 和在 get 函数的最底部添加 console.log('before found') 来检查 Client.find 是否阻塞。应该首先显示“找到之前”,当 db 的结果返回时,您应该会看到“找到” 是的! “之前”消息出现了,嗯,在哈哈之前。那我可以说代码是异步的吧? 它已被证明是我的问题 :) nodejs 没有等待来自 db 的结果并进行处理,这对我来说是异步的。 请注意,如果Client.findprocess.nextTick(function() blockSync(); ) 组成,那么您不会在当前事件循环中阻塞,但您会在下一个事件循环中阻塞。这是@Molda 建议的测试未涵盖的情况。 【参考方案1】:

Mongoose 的 exec() 是您代码中的异步函数。根据经验,昂贵的操作是异步的,而 cheap 操作不是*。昂贵意味着需要一些毫秒的操作,例如读取远程文件,访问(可能)远程数据库甚至读取本地文件。一些昂贵的异步操作示例:

request:加载外部网站。 fs:从您的系统中读取文件。大多数函数都是异步的,但由于读取文件的成本并不高,它们也有同步版本。 mongoose:正如@Molda 解释的那样,你的猫鼬调用是异步的。大多数猫鼬操作都是。

此外,异步函数的特点是它们会中断文件流,因此它们通常包含一个回调,执行流继续执行。在节点中,这些回调接受两个或多个参数作为约定,第一个参数是错误,其他参数是正在检索的数据。前面的例子:

request('httsp://google.com/', function(err, response, body)
  console.log(body);   // print the website's html on the terminal
);

fs.readFile('/config.js', function(err, message)
  console.log(message);   // print the contents of config.js on the terminal
);

User.find( id: 25 , function(err, user)
  console.log(user);  // print user's 25 data on the terminal
);

编辑:作为替代方案,您可以通过在find() 中包含回调来将代码简化一行,从而使此函数异步:

Client.find , (err, clients) ->
  if err then res.json new Internal(err.message, err.stack)
  if not clients then res.json new NotFound('No encontrado')

  res.json new Ok(clients, 'OK')

*请注意,昂贵便宜是高度相关的。例如parsing a huge file in JSON can be really expensive,它们是同步的,而读取小文件相对便宜。

【讨论】:

以上是关于Expressjs 路由请求和响应是异步的?的主要内容,如果未能解决你的问题,请参考以下文章

在 ExpressJS 响应中返回异步等待 try/catch 抛出错误 [重复]

异步和递归目录扫描,用于 Nodejs 和 Expressjs 中的文件列表

Expressjs在POST请求后不发送响应

NodeJS + ExpressJS:预检响应中的 Access-Control-Allow-Headers 不允许请求标头字段

学习使用ExpressJS 4.0中的新Router

使用 node-mysql 和 ExpressJS 在一个请求中执行两个或多个查询