一尘不染

Javascript / Node中的隐藏线程永远不会执行用户代码:是否可能,如果这样,是否会导致出现竞争状态的不可思议的可能性?

node.js

请参阅问题的底部以获取有关基于注释/答案的更新:该问题实际上是关于 不执行回调的 隐藏 线程的可能性。


我对涉及节点请求模块的潜在奥秘场景有疑问,其中:

  • 通过网络构造并执行 一个 完整的HTTP请求 (无论花费多少毫秒,甚至几秒钟)

  • 在运行时 在本地计算机上 执行单个功能 之前 (通常在十亿分之一秒内)-详情请参见下文

我主要将其发布为 健全性检查, 只是为了确保我不会误解有关Node / JS / Request模块代码的某些内容。

从“
请求”模块示例中(请参阅该部分的第二个示例),是这样的:

// Copied-and-pasted from the second example in the 
// Node Request library documentation, here:
// https://www.npmjs.com/package/request#examples

// ... My ARCANE SCENARIO is injected in the middle

var request = require('request')
  request(
    { method: 'GET'
    , uri: 'http://www.google.com'
    , gzip: true
    }
  , function (error, response, body) {
      // body is the decompressed response body 
      console.log('server encoded the data as: ' + (response.headers['content-encoding'] || 'identity'))
      console.log('the decoded data is: ' + body)
    }
  )

    // **************************************************** //
    // Is the following scenario possible?
    //
    // <-- HANG HANG HANG HANG HANG HANG HANG HANG HANG -->
    //
    // Let us pretend that the current thread HANGS here,
    // but that the request had time to be sent,
    // and the response is pending being received by the thread
    //
    // <-- HANG HANG HANG HANG HANG HANG HANG HANG HANG -->
    // **************************************************** //

.on('data', function(data) {
    // decompressed data as it is received 
    console.log('decoded chunk: ' + data)
  })
  .on('response', function(response) {
    // unmodified http.IncomingMessage object 
    response.on('data', function(data) {
      // compressed data as it is received 
      console.log('received ' + data.length + ' bytes of compressed data')
    })
  })

我已经在代码片段中指出了我的奥秘场景。

假设Node进程挂在指示的位置,但是该Node在内部(在一个 隐藏 线程中,对于Javascript是不可见的,因此没有调用 任何
回调)可以构造请求,并通过网络发送该请求;假设挂起继续进行,直到收到一个响应(例如,分为两个块)并等待Node处理。(这种情况肯定是不可思议的,而且我不确定理论上是否可能。)

然后假设挂起结束,并且上面的Node线程唤醒。进一步,假设(某种程度上)Node能够一直处理响应,直到执行上面代码中的回调函数为止(但无需移动到原始代码路径中代码的“挂起”点)
,即使这在理论上也是可能的)。

上述奥秘方案在理论上可行吗?如果是这样,在将'data'事件安排在对象上之前,是否不通过网络接收数据包并进行组合,准备将其传递给回调函数?在这种情况下,如果有可能,我会想象该'data'事件将被错过。

再一次,我了解到这是一个神秘的场景-考虑到内部机制和编码,从理论上讲甚至是不可能的。

这是我的问题-上面的奥秘场景在极不可能的比赛条件下,在理论上是否可行?

我只是为了确保我没有错过一些关键点。谢谢。


更新 :从评论和答案:我现在已经澄清了我的问题。“
arcane场景”将要求有一个HIDDEN线程(因此无法执行任何USER代码,包括CALLBACKS)来构造请求,通过网络发送该请求,并接收响应-
无需触发任何回调,包括'data'回调-在'response'准备好调用回调的那一刻停止,等待(单个)可见JS线程唤醒。


阅读 253

收藏
2020-07-07

共1个答案

一尘不染

不,这不会发生。

是的,确实有“隐藏”的后台线程为异步方法工作,但是 这些 后台线程 不调用callbacks
。javascript的所有执行都确实在同一个线程上进行,顺序,同步。该data事件回调将始终 异步 执行,即在当前脚本/函数运行完成之后。

虽然在创建回调并将其附加到事件发射器之前确实确实已经有来自网络的数据包到达了,但是侦听最低级别数据包的回调总是在发送请求之前创建的-它是本地“
makeRequest”的一个参数”方法,并且可以从一开始就被调用。因此,当数据包确实在当前脚本(仍由构造事件发射器和附加处理程序占用)完成之前到达时,此
事件将排队 ,并且仅在事件循环准备好后(在下一回合)执行回调。届时,data肯定会创建并附加事件回调。

2020-07-07