What i all know about call stack is:

  1. 如果只有一个函数被调用,则它将被推送到调用堆栈,并在其作业(job)完成或遇到返回语句时被移除.

  2. 如果一个函数调用另一个函数,则两个函数都留在调用堆栈中并按顺序弹出;子级,然后是父级.

  3. 如果子函数中有异步代码,则像语句2中所说的那样弹出both个.但当将来完成异步作业(job)时,子(?)函数将被放入Task Queue中,然后放入Call Stack中.

But when i used debugger in VSCode:

  1. 我发现在完成setTimeout()之后,父函数和子函数都在调用堆栈中.让我的信念变成虚假的only child being in call stack.
  2. 在下面的promise 解析后的代码中,在异步代码完成后,调试器中只有const dummy2 = 'abc'可用,而const dummy = 'XYZ' 不可用

function asyncfun(){
  const innerDummy = '123'
 return new Promise((resolve, reject)=>{
      setTimeout(()=>{
        resolve('You are eligible for voting.');
      },5000)
 })
}

function outer(){
  const dummy = 'XYZ';
  asyncfun().then((msg)=>{
    const dummy2 = 'abc'
    console.log('Promise result:',msg)
  })
}
outer();

  1. 请注意,我已经在setTimeOut()回调中设置了断点:resolve('You are eligible for voting.');,以查看promise 完成/解析后谁在调用堆栈中,这将在future 5秒内发生.同时,当执行达到此行时,innerDummy不可用.

  2. console.log('Promise result:',msg)行的另一个断点,在上面的断点之后执行.这里的dummy不可用,但dummy2可以使用.

  3. 由于上述变量在调试器中不可用,我感到困惑的是,是否将部分函数重新推送到调用堆栈或其他什么地方?

推荐答案

我认为您在这里可能会混淆调用堆栈和作用域的概念.

我发现在setTimeout()完成后,父函数和子函数都在调用堆栈中.使我错误地相信独生子是在调用堆栈中.

这里的setTimeout的完成是即时的,因为您只是返回一个将被推到任务队列中的promise .此时,您的调用堆栈应该包含outer=>;asyncfunc.

您从asyncfunc返回promise ,就执行的同步部分而言,OUTER完成了.然后,在超时过后,JS引擎在内部将超时回调推送到任务队列.从概念上讲,此时的任务队列只包含setTimeout的匿名回调,但一些调试器以不同的方式显示asnyc,有时您可以看到回调被处理的位置的跟踪(对于不同的JS实现,如Node、Deno或Chrome,这将有所不同,因为回调处理实际上并不是JS语言的一部分,只有它本身是同步的).

在下面的promise 解析后的代码中,在异步代码完成后,调试器中只有Const Dummy2=‘abc’可用,而不是Const Dummy=‘XYZ’

我假设您的断点在console.log('Promise result:', msg)左右.如果是这种情况,dummydummy2变量都将可用(您可以在dummy2声明后通过控制台记录它们来判断这一点),但是dummy不是您的本地作用域的一部分,所以您应该在调试面板中的闭包下看到它.

因此,回答您的主要问题--不是,只有异步回调被任务队列推送到调用堆栈.基本上只有这个

() => {
  resolve('You are eligible for voting.');
},

在超时后在调用堆栈中结束. 如果您询问.then(..)之后该函数会发生什么情况,那么在所谓的"微任务队列"中会有一些不同的处理方式.将您的代码放在此处https://www.jsv9000.app/以直观地判断您的执行情况可能会很有帮助.

希望这能有所帮助:)

Javascript相关问答推荐

使用expressjs加载Nuxt版本=3.9.0(自定义服务器)

单击树元素时阻止焦点事件触发?

Toast函数找不到其dis

JavaScript Date对象在UTC中设置为午夜时显示不正确的日期

如何使用React渲染器放置根dis?

JavaScript文本区域阻止KeyDown/KeyUp事件本身上的Alt GR +键组合

当在select中 Select 选项时,我必须禁用不匹配的 Select

if/else JavaScript中的条件行为

字节数组通过echo框架传输到JS blob

react—router v6:路由没有路径

成功完成Reducers后不更新状态

单击ImageListItemBar的IconButton后,在Material—UI对话框中显示图像

为什么Mutations 观察器用微任务队列而不是macrotask队列处理?

从包含数百行的表中获取更改后的值(以表单形式发送到后端)的正确方法是什么?

使用POST请求时,Req.Body为空

这个值总是返回未定义的-Reaction

从另一个数组中的对应行/键值对更新数组中的键值对对象

为什么延迟在我的laravel项目中不起作用?

为什么我不能使用其同级元素调用和更新子元素?

使用createBrowserRoutVS BrowserRouter的Reaction路由