Display asynchronous stacks in the debugger
Categories
(DevTools :: Debugger, enhancement, P5)
Tracking
(Not tracked)
People
(Reporter: ejpbruel, Unassigned)
References
(Blocks 1 open bug, )
Details
Comment 2•10 years ago
|
||
Updated•10 years ago
|
Updated•8 years ago
|
Updated•7 years ago
|
Comment 3•7 years ago
|
||
Updated•7 years ago
|
Updated•6 years ago
|
Updated•6 years ago
|
Updated•5 years ago
|
Updated•5 years ago
|
Updated•5 years ago
|
Updated•5 years ago
|
Updated•5 years ago
|
Updated•5 years ago
|
Updated•5 years ago
|
Comment 6•5 years ago
|
||
What's being requested here is actually a much stranger feature than it might seem. It's certainly not a duplicate of dbg-async-stacks. I don't think it's a feature we really want to focus on at the moment, so I'm marking it P5.
Yes, we do have stacks attached to promises when they are created and resolved. Yes, that information could be helpful to developers working in promise-based code. But those stacks cannot be spliced onto the ordinary live call stack in a reasonable way; they're almost the inverse of a call stack.
In an ordinary call stack, a caller is a function call that is temporarily suspended until its callee returns a value. That terminology may sound like I'm describing async/await, but it is actually a perfectly fine description of the synchronous case. In a call stack, only the youngest frame actually runs; all its callers are suspended waiting for their callees.
An async function call is very similar: the awaiter is temporarily suspended waiting for its awaitee to return a value. They're connected via a promise and an internal generator object, rather than just being frames stacked directly on top of each other; but in terms of who is running and who is blocked, who is producing and who is consuming, it's exactly the same as a synchronous call.
So the two cases' common structure is: suspended consumers below running producers.
Now consider the case where we're running a promise callback, attached to the promise with then
or catch
. A promise records the stack at which it was created, and the stack at which it was resolved. The promise creation stack is not a suspended consumer of the callback's value; it has nothing to do with that. The promise resolution stack does not show a suspended consumer of the callback's value - in fact, it's almost the opposite! It's the code that provided the value the callback is processing, making it more analogous to a callee of the callback than its caller. In the "common structure" described above, it should appear above the callback, not below it. It would be wildly confusing to display it as an extension of the callback's JS stack.
Since then
takes a callback and returns a promise of its value, the closest thing to a 'caller' of that callback would be the other callbacks chained on to the promise returned by then
. That is a suspended computation (represented as a closure) awaiting the value of the present callback.
Of course, a promise may have any number of callbacks attached to it - but this is true both of pure Promise-based code and of async/await code: there's no reason a single promise can't have many async functions awaiting it. The choice of which one to display as the "true" stack arises either way. I believe that promises with only one callback are the common case, however, so it may not be a problem to do some dumb strategy, like picking the first callback.
Updated•5 years ago
|
Comment 7•5 years ago
|
||
It might make sense if we instead captured a stack when we attach a callback to a promise. That is, a promise's set of reactions would associate a captured stack with each reaction. Attaching the callback is when the caller actually "expresses interest" in the value of the promise, roughly analogous to when a caller "expresses interest" in the return value of a callee. That's the answer to the question, "Why am I here?" which is what I think people often want out of stacks.
Updated•5 years ago
|
Comment 8•5 years ago
|
||
This is one of the main bugs where live stack would will probably happen. Shouldn't it be attached to the live stacks meta or is there another place where implementation happens?
Comment 9•5 years ago
|
||
This is not about live stacks at all, it's about captured stacks, and it's a confusing way to present them. See comment 6.
Updated•5 years ago
|
Updated•5 years ago
|
Updated•5 years ago
|
Updated•5 years ago
|
Comment 10•5 years ago
|
||
Jason, I assume this can be duped against existing captured stack bug?
Updated•5 years ago
|
Description
•