Скажем, у вас есть эта последовательность функций (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()
, функция next , вызываемая на этом уровне, равна 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
Вот куда я отправляюсь, пытаясь отобразить стек вызовов.Кажется, что это сформировало бы дерево.Теперь представьте несколько асинхронных процессов, начинающихся одновременно.Тогда это как множественные ветви на дерево.Таким образом, вместо стека вызовов, дерево вызовов.Это заставляет меня наконец задаться вопросом, как именно оценивается стек вызовов. Когда следующая функция в последовательности помещается в стек вызовов, и как обновляют / удаляют последнюю завершенную функцию и возвращаются к следующему месту в стеке вызовов /tree.
Хотите знать, можете ли вы указать какие-либо ресурсы, которые могли бы описать это, или, возможно, даже объяснить, как будет выглядеть стек вызовов в примере, который я описал выше.