【问题标题】:Why does setTimeout still work when using an Express app?为什么使用 Express 应用时 setTimeout 仍然有效?
【发布时间】:2021-01-21 22:40:47
【问题描述】:

我正在制作一个 Express 应用程序,我打算使用 setTimeout 在一定时间后使与第三方 API 一起使用的访问令牌无效。我认为它可能不起作用,因为像 setTimeout 这样的异步函数被推送到事件队列中,并且在其他所有东西都完成运行之前不会运行。 Express 应用程序(我假设)一直在运行,因为它一直在监听请求,所以我认为由于程序永远不会完成,所以 setTimeout 永远不会运行。但 setTimeout 运行良好且准时。

这怎么可能? Express 的监听部分是否有非 JS 的东西,还是我误解了 async 和事件队列?

【问题讨论】:

  • “还是我误解了异步和事件队列?” - 是的。
  • 请求来自事件队列。所以当它监听请求时它是空闲的,等待请求到达事件队列。如果它们首先出现,它将处理任何其他事件。

标签: javascript node.js express asynchronous settimeout


【解决方案1】:

Express 服务的请求都像 setTimeout() 一样通过事件队列,因此它们共享同一个事件队列并且可以很好地交错。

因此,当传入请求到达 Express 服务器时,一些较低级别的 TCP 代码将该传入连接插入到事件队列中。下一次 Express 完成执行某事时,nodejs 解释器返回事件队列并抓取下一个事件。这可能是下一个传入请求,可能是为请求提供服务的一些中间异步操作(例如数据库查询完成),也可能是您的setTimeout()

事件通常以 FIFO(先进先出)的方式提供服务,但当队列中有多种不同类型的事件等待运行时,不同类型的事件之间存在一些优先级会影响排序细节。

Express 应用程序(我假设)一直在运行,因为它一直在监听请求,所以我认为由于程序永远不会完成,所以 setTimeout 永远不会运行。但是 setTimeout 运行良好且准时。

在这种情况下,“始终运行”仅表示它已准备好并等待传入​​请求。每当 JS 解释器返回到下一个事件的事件循环时,事件队列中的其他东西(如计时器)都能够正常运行。

【讨论】:

  • 这是有道理的,请求和计时器都在事件队列中,因此它们不会相互干扰。 “准备好并等待传入​​的请求”,这不是编程行为,例如 while 循环或其他什么吗?这意味着调用堆栈永远不会为空,因为该等待函数始终在运行,因此事件队列、请求或计时器中的任何内容都不能被拉入?这是我现在不明白的部分。
  • @AdnanZaman - 不。Nodejs 是一个事件驱动的环境。您不会在循环中等待传入的网络请求。您只需为传入事件注册一个事件处理程序,传入流量将触发一个事件,该事件将导致您的回调通过事件循环被调用。
猜你喜欢
  • 2020-09-09
  • 2023-03-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-24
  • 2015-12-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多