调用栈为空后,Node Js 的事件循环内部是否只有一些特定的回调?

Are there only some spefiic callbacks that are processed inside the event loopin Nodejs after the call stack is empty?

1.const geoCode = (address, callback)=> {

setTimeout(()=> {
 const data ={
    longitude: 0,
    latitude: 0
}
  callback(data)
  }) 

}

geoCode('John', (data)=>{
 console.log(data)
 })


2. const forecast =(longitude, latitude, callback) =>{

   const url = `https://api.openweathermap.org/data/2.5/weather? 
   lat=${latitude}&lon=${longitude}&appid=ff894a55e90b66e3d6cd4b2bd8ea6509`
   console.log(url);

   request({url, json:true}, (error, {body})=>{
   if(error) {
      callback('Unable to connect to the Internet', undefined)
   } else if(body.error){
      callback('Please try again', undefined)
   } else {
      callback(undefined,body.main)
      
   }

})
}

嗨,我是 Node.js 的新手,很难理解回调、回调队列及其处理方式。我的问题是什么样的回调会进入 Node 中的回调队列?是否必须是节点特定 APIS、npm 包和 setTimeOut、request() 等 Web API 内部的回调,才能添加到回调队列中,以便在主调用堆栈为空后执行?或任何类型的回调进入 node.js?

中的回调队列

node.js 中的任何事件驱动项目最终都有一些代码在将来的某个时间在事件队列中插入回调。这可以是内置项,如 setTimeout()setInterval()、通过 net 模块联网、通过 fs 模块异步文件 I/O 等。 . 或者也可以是使用插件 API 的本机代码插件,触发事件并导致回调被插入到事件队列中。这是未来某个时间发生的任何异步事件如何在 node.js 中工作的关键。每个异步操作都使用相同的机制。

事件循环实际上相当复杂,包含一堆不同类型的队列。一个用于 I/O,一个用于定时器,一个用于 promises。他们有不同的优先级和一定的顺序。例如,承诺比其他类型的事件具有更高的优先级。计时器的工作方式实际上与其他计时器略有不同,但您仍然可以在逻辑上将它们视为一组计时器,当它们被触发时,它们会导致回调被调用。

除了定时器,当一个事件想要被触发时,一些本地代码会在某处插入一个回调到事件队列的适当部分。当事件循环到达特定类型的事件时,它将调用与该事件关联的回调并执行与该回调关联的 Javascript 。当该回调 returns 时,它将继续围绕事件循环寻找其他事件 运行 回调。如果找不到任何准备就绪的东西,它就会休眠,直到有东西插入事件队列或直到下一个计时器准备好触发。

计时器使用排序的链表,下一个计时器位于列表的前面。事件循环只是将当前系统时间与列表前面的计时器的触发时间进行比较。如果在事件循环开始检查定时器时触发该事件的时间(或超过定时器),则执行与该定时器关联的回调并将其从链接列表中删除。如果不是,事件循环会继续处理其他类型的事件。