簡體   English   中英

NodeJS事件循環多個請求

[英]NodeJS Event Loop Multiple Request

我對以下代碼有疑問(來源: https//blog.risingstack.com/node-js-at-scale-understanding-node-js-event-loop/ ):

'use strict'  
const express = require('express')  
const superagent = require('superagent')  
const app = express()

app.get('/', sendWeatherOfRandomCity)

function sendWeatherOfRandomCity (request, response) {  
  getWeatherOfRandomCity(request, response)
  sayHi()
}

const CITIES = [  
  'london',
  'newyork',
  'paris',
  'budapest',
  'warsaw',
  'rome',
  'madrid',
  'moscow',
  'beijing',
  'capetown',
]

function getWeatherOfRandomCity (request, response) {  
  const city = CITIES[Math.floor(Math.random() * CITIES.length)]
  superagent.get(`wttr.in/${city}`)
    .end((err, res) => {
      if (err) {
        console.log('O snap')
        return response.status(500).send('There was an error getting the weather, try looking out the window')
      }
      const responseText = res.text
      response.send(responseText)
      console.log('Got the weather')
    })

  console.log('Fetching the weather, please be patient')
}

function sayHi () {  
  console.log('Hi')
}

app.listen(3000);

我有這些問題:

  1. 當getWeatherOfRandomCity方法中的superagent.get( wttr.in/${city} )http://wttr.in/sf發出Web請求時,該請求將被置於任務隊列而不是主要調用堆棧正確嗎?
    1. 如果主調用堆棧上有方法(即主調用堆棧不為空),則結束事件附加到superagent.get( wttr.in/${city} ).end(...) (即被推到任務隊列)直到主調用堆棧為空是否正確才會被調用? 換句話說,在事件循環的每個刻度上,它將從任務隊列中獲取一個項目?
    2. 假設有兩個對localhost:3000/請求localhost:3000/一個接一個地進來。 第一個請求將推送堆棧上的sendWeatherOfRandomCity,堆棧上的getWeatherOfRandomCity,然后將web請求superagent.get( wttr.in/${city} ).end(...)放在后台隊列中,然后console.log('Fetching the weather, please be patient') ,然后sendWeatherOfRandomCity將從堆棧彈出,最后sayHi()將被推入堆棧,它將打印“Hi”並彈出堆棧,最后附加到superagent.get( wttr.in/${city} ).end(...)結束事件將從任務隊列中調用,因為主調用堆棧將為空。 現在,當第二個請求到來時,它會將所有與第一個請求相同的內容推送到主調用堆棧,但是第一個請求(仍然在任務隊列中)的結束處理程序將首先運行,或者將內容推送到主調用第二個Web請求的堆棧會先運行嗎?

當您發出http請求時,libuv會發現您正在嘗試發出網絡請求。 libuv和node都沒有任何代碼來處理網絡請求涉及的所有這些操作。 而是libuv將請求委托給底層操作系統。

它實際上是內核,它是我們操作系統的重要組成部分,可以完成真正的網絡請求。 Libuv用於發出請求,然后它只是等待操作系統發出一個信號,表明某些響應已經回到請求。 因此,由於Libuv將完成的工作委托給操作系統,操作系統本身決定是否制造新的威脅。 或者只是一般如何處理發出請求的整個過程。 每個不同的操作系統都有不同的方法來處理這個:在linux上它是epoll,在mac os中它被稱為kqueue,在windows中它被稱為GetQueuedCompletionStatusEx。

事件循環中有6個階段,其中一個是i / o輪詢。 每個階段都優先於其他階段。 1號總是定時器。 當時間到了,(或事件完成)定時器的回調將被調用到事件隊列,定時器功能也將移動到事件隊列。 然后事件循環將檢查調用堆棧是否可用。 調用堆棧是函數執行的地方。 你可以一次做一件事,調用堆棧強制我們只能在調用堆棧的頂部有一個函數,這是我們正在做的事情。在JAVASCRIPT RUNTIME中無法同時執行兩件事。

如果調用堆棧為空意味着刪除了main()函數,則事件循環將推送定時器函數調用堆棧並執行您的函數。 在主函數完成之前,所有Async回調都不會運行。

因此,當I / O輪詢階段處理傳入數據和連接時,使用相同的路徑定時器函數如何跟隨,將執行處理提取的函數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM