function foo() { console.log('foo called') return Promise.resolve(5) } foo() .then(res => { console.log(res) }) console.log('hi')
Console Output:
1.) 'foo called' 2.) 'hi' 3.) 5
My main question is what is actually happening when the global execution context thread is finished and popped of the execution stack. How does JS/V8 know where this Promise Object is in memory if the Promise Object is not assigned to a variable within global execution context? How does it know where to update the promise value and trigger the onfullfilment function ?
Advertisement
Answer
Looking at the V8 source code, we can see that when a Promise is created, it is bound to the current execution context, even if you don’t store it in a variable.
Node* const native_context = LoadNativeContext(context); Node* const promise = AllocateAndInitJSPromise(context);
Looking at how promises are implemented, we can see that Promise resolution chains are implemented as a simple linked list:
The
PromiseReaction
objects form a singly-linked list […]. On theJSPromise
instance they are linked in reverse order, and are turned into the proper order again when scheduling them on the microtask queue.
Shortly put, V8 binds Promises to the execution context even if you don’t store them in a variable and Promise chains are implemented as linked lists meaning it’s easy to track back once the Promise actually resolves.
For a more general better understanding of how async operations interact with one another, check out this video by Jake Archibald on the Javascript event loop.