Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript NodeJS事件循环多请求_Javascript_Node.js_Event Loop - Fatal编程技术网

Javascript NodeJS事件循环多请求

Javascript NodeJS事件循环多请求,javascript,node.js,event-loop,Javascript,Node.js,Event Loop,我对下面的代码有一个问题(来源:): 我有以下问题: 当getWeatherOfRandomCity方法中的superagent.get(wttr.in/${city})向http://wttr.in/sf例如,该请求将被放置在任务队列上,而主调用堆栈是否正确? 如果主调用堆栈上有方法(即主调用堆栈不是空的),则附加到superagent.get(wttr.in/${city}).end(…)(将被推送到任务队列)的end事件将不会被调用,直到主调用堆栈为空,是否正确?换句话说,在事件循环的每一

我对下面的代码有一个问题(来源:):

我有以下问题:

  • 当getWeatherOfRandomCity方法中的
    superagent.get(
    wttr.in/${city}
    http://wttr.in/sf
    例如,该请求将被放置在任务队列上,而主调用堆栈是否正确?
  • 如果主调用堆栈上有方法(即主调用堆栈不是空的),则附加到
    superagent.get(
    wttr.in/${city}
    ).end(…)
    (将被推送到任务队列)的end事件将不会被调用,直到主调用堆栈为空,是否正确?换句话说,在事件循环的每一个滴答声上,它将从任务队列中获取一个项目
  • 假设有两个对
    localhost:3000/
    的请求相继出现。第一个请求将把sendWeatherOfRandomCity推到堆栈上,把getWeatherOfRandomCity推到堆栈上,然后是web请求
    superagent.get(
    wttr.in/${city}
    )。end(…)
    将被放在后台队列上,然后
    console.log('获取天气,请耐心等待)
    ,然后sendWeatherOfRandomCity将弹出堆栈,最后将
    sayHi()
    推送到堆栈上,它将打印“Hi”并弹出堆栈,最后是附加到
    superagent.get(
    wttr.in/${city}
    )的end事件。由于主调用堆栈为空,因此将从任务队列调用end(…)
    。现在,当第二个请求到来时,它会将所有这些与第一个请求相同的东西推送到主调用堆栈上,但是第一个请求(仍然在任务队列中)的终端处理程序会首先运行,还是第二个web请求推送到主调用堆栈上的东西会首先运行

  • 当您发出http请求时,libuv会看到您正在尝试发出网络请求。libuv和node都没有任何代码来处理与网络请求有关的所有这些操作。相反,libuv将发出的请求委托给底层操作系统

    它实际上是内核,它是我们操作系统的重要组成部分,负责真正的网络请求工作。Libuv用于发出请求,然后它只是等待操作系统发出一个信号,表明某个响应已返回到请求。因此,由于Libuv将完成的工作委托给操作系统,因此操作系统本身决定是否制造新的威胁。或者只是一般来说如何处理提出请求的整个过程。每个不同的操作系统都有不同的方法来处理这个问题:在linux上它是epoll,在mac操作系统中它被称为kqueue,在windows中它被称为GetQueuedCompletionStatusEx

    事件循环中有6个阶段,其中一个是i/o轮询。每个阶段都比其他阶段优先。1号总是计时器。当时间到了,(或事件完成)计时器的回调将被调用到事件队列,计时器函数也将移动到事件队列。然后事件循环将检查它的调用堆栈是否可用。调用堆栈是函数执行的地方。您可以一次执行一件事情,而调用堆栈强制我们只能在调用堆栈的顶部执行一个函数,这就是我们正在执行的事情。在JAVASCRIPT运行时,无法同时执行两件事情

    如果调用堆栈为空,则意味着main()函数被删除,事件循环会将计时器函数推送到调用堆栈,并执行您的函数。在主函数完成之前,任何异步回调都不会运行


    因此,当i/o轮询阶段处理传入的数据和连接时,如果计时器函数遵循相同的路径,则处理抓取的函数将被执行。

    您的任务队列概念是有缺陷的。异步操作在您调用它们时立即启动-它们不会进入任务队列。结果完成后将在事件队列中排队,并按照其排队顺序(完成的顺序,从而触发回调)提供服务。只有当解释器没有运行任何其他Javascript(它是单线程的)时,才会从事件队列中提取事件(这将导致调用回调)。此外,传入事件不会按您描述的方式推送到堆栈上。有一个单独的事件队列,它与堆栈没有连接。当node.js运行完所有其他Javascript后,它将从事件队列(具有空堆栈)中提取下一个事件,并调用与其关联的回调。这会触发回调中的一些Javascript运行。该回调以前可能在函数闭包中保存了状态(闭包是垃圾收集的独立对象,不在堆栈上)。但假设异步操作完成,其结果和回调被放置在事件队列中,但主调用堆栈中仍然有代码。因此,在主调用堆栈为空之前,不会调用事件队列中的回调。正确吗?正确。js是单线程的,一次只做一件事。它运行当前的JS片段,直到它将控制权返回给系统为止,此时它从事件队列中提取下一个内容并运行与之相关的回调。每个回调都以一个空堆栈开始。这就是nodejs描述“事件驱动”的含义。事件发生时,运行一些与该事件相关联的Javascript,完成该Javascript,查看事件队列中是否有其他事件并运行该事件,依此类推。只有一个Javascript堆栈,当调用事件队列中的每个回调时,该堆栈将为空。所以我不知道你的问题是什么意思,因为它暗示可能有多个堆栈。只有一个。
    '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);