Function 异步调用堆栈的实现方式

Function 异步调用堆栈的实现方式,function,compiler-construction,callstack,Function,Compiler Construction,Callstack,假设您有这个函数序列(JavaScript) 尝试使其具有某种复杂的调用堆栈 我想知道的是调用堆栈在不同的时间点是什么样子的。例如,c();C(y);d()顺序。调用c()时,该级别下一个要调用的函数是c()。因此,它似乎会推到堆栈上(在计算c()之前),c()是返回位置。然后转到e()和f()(暂时忽略)。然后检查调用堆栈并返回到C()。然后是同样的过程。但是由于C()是异步的,所以在C()完成之前,它会转到d()。所以是这样的: c c c c c c c

假设您有这个函数序列(JavaScript)

尝试使其具有某种复杂的调用堆栈

我想知道的是调用堆栈在不同的时间点是什么样子的。例如,
c();C(y);d()
顺序。调用
c()
时,该级别下一个要调用的函数是
c()
。因此,它似乎会推到堆栈上(在计算
c()
之前),
c()
是返回位置。然后转到
e()
f()
(暂时忽略)。然后检查调用堆栈并返回到
C()
。然后是同样的过程。但是由于
C()
是异步的,所以在
C()
完成之前,它会转到
d()
。所以是这样的:

c   c   c   c   c   c     c    ...?
    C   C   C   C   C    /  \
        e   e   f       C    d
            f
这就是我在尝试绘制调用堆栈时的想法所在。它似乎会形成一棵树。现在想象一下,多个异步进程几乎同时启动。然后就像一棵树的多个分支。因此,不是调用堆栈,而是调用树。这让我最后怀疑调用堆栈到底是如何计算的。当序列中的下一个函数被推到调用堆栈上时,以及它们如何更新/删除最后一个完成的函数并返回到调用堆栈/树中的下一个位置


想知道您是否可以指出任何可能描述这一点的资源,或者甚至可以解释我上面描述的示例中调用堆栈的外观。

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

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

c c c c c C C
  e   f     g

但是似乎返回地址是下一个函数,我不知道它是如何不同的,也不确定异步情况下发生什么。不,返回地址位于当前函数的中间。在本例中,当前函数中的下一个是另一个调用(下一个函数)。,但它可以是任何东西。这实际上不是程序集问题。不要将其视为单个调用堆栈。将异步执行视为线程中的多个调用堆栈。
c c c c c C C
  e   f     g