如何实现异步调用堆栈

问题描述 投票:0回答:1

假设你有这个功能序列(JavaScript)....

A(function(){
  console.log('done')
})

function A(done) {
  a()
  B(D, done)
}

function B(x, y) {
  x(function(){
    c()
    C(y)
    d()
  })
}

function C(z) {
  g()
  setTimeout(z, 1000)
}

function D(z) {
  h()
  setTimeout(z, 2000)
}

function a() {
  b()
  c()
}

function b() {
  // ... sync stuff
}

function c() {
  e()
  // ... sync stuff
  f()
}

function d() {
  // ... sync stuff
}

尝试使它具有一种复杂的调用堆栈。

我想知道的是调用堆栈在不同时间点的样子。例如,c();C(y);d()序列。当调用c()时,在该级别调用的下一个函数是C()。所以看起来它会推到堆栈上(在评估c()之前),C()是返回位置。然后它去e()f()(暂时忽略它)。然后它检查调用堆栈并返回C()。然后同样的过程。但由于C()是异步的,所以在d()完成之前它会进入C()。所以它是这样的:

c   c   c   c   c   c     c    ...?
    C   C   C   C   C    /  \
        e   e   f       C    d
            f

这是我在尝试绘制调用堆栈时的想法。好像它会形成一棵树。现在想象多个异步进程在同一时间开始。然后它就像树的多个分支。所以不是调用堆栈,而是调用树。这让我终于质疑调用堆栈的评估方式。当序列中的下一个函数被推送到调用堆栈时,以及它们如何更新/删除最后完成的函数并找到返回调用堆栈/树中下一个位置的方法。

想知道你是否可以指出任何可能描述这个的资源,或者甚至可能解释调用堆栈在我上面描述的例子中的样子。

function compiler-construction callstack
1个回答
1
投票

当你调用一个函数时,你会在堆栈上推送一个返回地址,而不是下一个要调用的函数。然后被调用的函数将在堆栈上创建自己的框架(您可以考虑该框架的返回地址部分或与框架分离,具体取决于您如何看待它。当函数返回时,它将弹出其框架并返回到返回地址(也将隐式或显式地弹出返回地址 - 详细信息取决于CPU / VM体系结构。

因此,对于您的示例,随着时间的推移调用堆栈看起来更像

c c c c c C C
  e   f     g
© www.soinside.com 2019 - 2024. All rights reserved.