【问题标题】:How does the webapi execute the settimeout javascriptwebapi如何执行settimeout javascript
【发布时间】:2020-04-01 19:53:13
【问题描述】:

我对 settimeout 完成后将什么放入回调队列中是否放入函数名称/函数定义(我们作为参数传递给 settimeout)或调用的函数感到困惑

function cb(){
  console.log("Hi!")
}
setTimeout(cb,2000) // what will be put on the callback queue after 2 sec cb or cb()

所以现在如果我打电话给setTimeout(cb,2000) 之后它将在回拨队列中放入cb or cb()

如果我假设它只像那样放置 cb,并且当事件循环将 cb 放入调用堆栈时,它将执行 cb 函数 所以如果是这样的话,那么如果我有:

function cb(num){
      console.log(num);
      console.log("Hi!")
    }

并调用setTimeout(cb,2000,5),因此对于这种情况,在计时器完成后并且如果它只将 cb 放入回调队列中,那么当事件循环将 cb 放入调用堆栈时,它如何记住或传递 num 参数(在这种情况下为值 5),因为它将 5 记录到控制台。

非常感谢任何帮助,因为我无法为这种混乱设置心智模型。

【问题讨论】:

  • 向我们展示完整的代码
  • 这与代码无关,我想知道 web api 在回调队列中放置了什么,它是否放置了回调函数定义(我们传递给 setTimeout 的参数或回调)或确实而是回调队列中调用的回调函数
  • setTimeout(cb,2000) 。调用setTimeoutcb指向的函数地址。该地址的内存包含cb函数的字节码

标签: javascript event-loop webapi


【解决方案1】:

当您执行 setTimeout(cb,2000,5) 时。您将 3 个参数推送到底层实现堆栈:

  • cb函数地址
  • 整数 2000
  • 整数 5

Chrome(或您使用的 Node 或 w/e 实现)本机 API 会使用这些参数调用。请注意,setTimeout不是 javascript v8 引擎的一部分。

我没有查看源代码,但我相信接下来会发生:事件循环计算一个新的时间,并与回调函数的内存地址和其他参数一起记住它。当时机成熟时,本机 API 唤醒并触发调用回调及其参数的本机代码。所以:

setTimeout(function() {console.log(arguments)}, 1, 2, 3, 4)
// prints [2, 3, 4]

您可能对此感兴趣,对函数的引用可以包含参数:

b = function(){console.log(arguments)}
ba = b.bind(1,2,3)
setTimeout(ba, 4,5,6)
// prints [2, 3, 5, 6]
// where 1 is this, and 4 is the timeout

【讨论】:

  • 我无法理解,请您详细说明一下,首先我想要一个简短的答案,在 setTimeout 运行 2 秒后,我们将在回调队列中放入 setTimeout 的回调函数或地址回调函数或调用的回调函数
猜你喜欢
  • 1970-01-01
  • 2022-01-08
  • 2020-08-26
  • 1970-01-01
  • 2011-06-19
  • 2021-04-15
  • 1970-01-01
  • 2018-03-11
  • 2016-02-18
相关资源
最近更新 更多