Let's consider this code:
async function testFunction() {
// event loop 1 - before any "await", we are still in original event loop, right?
const result = await Promise.resolve('abc');
// event loop 2 - we have a new event loop
return result;
}
// event loop 1
testFunction().then(result => {
// event loop 2? Or new event loop?
})
Does event loop changes again after async
function done all asynchronous operations? Is the event loop right before return
statement the same as in the then
statement?
And is there an easy way to check it?
I'm working with some synchronous API that needs to be executed in the same event loop and I want to be sure it will work.
EDIT:
To make it more clear, this is the real life example:
async function dbTransaction(tableName, transactionMode) {
const db = await _dbPromise;
return db.transaction([tableName], transactionMode).objectStore(tableName);
}
Can I use the transaction returned by this asynchronous function?
Some related MDN info:
https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API/Using_IndexedDB#Adding_data_to_the_database
And important quote:
Now that you have a transaction you need to understand its lifetime. Transactions are tied very closely to the event loop. If you make a transaction and return to the event loop without using it then the transaction will become inactive.
EDIT 2:
One more thing - the answer is yes - the transaction is usable after const objectStore = await dbTransaction(DB_IMAGE, DB_OP_READWRITE)
. Only if I await something else I get TRANSACTION_INACTIVE_ERR
error - which makes sense.
So is it by design? Does it mean it is indeed in the same event loop iteration?
A transaction is only valid on a given stack. When some asynchronous work is done, ie the browser gets a handler to indexedDB here:
const db = await _dbPromise;
a new stack is created and it continues till the end of that function. But apart from the main stack, there's also a microtask stack and on that stack go all callbacks from promises and observers. If a promise is marked as resolved while executing instructions from a given stack, it is immediately called after the main stack empties and a transaction is still available there. (You can think of stack + microtasks as one 'tick' of a loop after which javascript passes control back to the event loop that decides what to do next).
So in your example:
async function testFunction() {
// tick 1 synchronous
const result = await Promise.resolve('abc');
// tick 1 microtask 1 (up resolved through the execution of the stack)
return result;
}
// tick 1
testFunction().then(result => {
// tick 1 microtask 2 (resolved through the execution of microtask 1)
})
You can get some info by checking performance panel:
This video might clear what an event loop is and how it works: https://vimeo.com/254947206
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.