【发布时间】:2019-08-03 06:17:47
【问题描述】:
假设你有这个函数序列(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() 是异步的,它会在C() 完成之前转到d()。所以是这样的:
c c c c c c c ...?
C C C C C / \
e e f C d
f
这就是我在尝试绘制调用堆栈时的想法。它似乎会形成一棵树。现在想象一下多个异步进程几乎同时开始。然后它就像一棵树的多个分支。所以不是调用堆栈,而是调用树。这让我最终质疑调用堆栈是如何被评估的。 当序列中的下一个函数被推入调用堆栈时,以及它们如何更新/删除最后完成的函数并找到返回调用中下一个位置的方法堆栈/树。
想知道您是否可以指出任何可能描述这一点的资源,或者甚至可以解释调用堆栈在我上面描述的示例中的外观。
【问题讨论】:
-
这真的不是一个装配问题。不要将其视为单个调用堆栈。将异步执行视为线程中的多个调用堆栈。
标签: function compiler-construction callstack