让我们考虑以下代码:
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?
})
在async
函数完成所有异步操作之后,事件循环会再次更改吗?在return
语句之前的事件循环是否与then
语句中的相同? ?
有没有简单的方法可以检查它?
我正在使用一些需要在同一事件循环中执行的同步API,我想确保它可以正常工作。
编辑:
更清楚地说,这是现实生活中的例子:
async function dbTransaction(tableName, transactionMode) {
const db = await _dbPromise;
return db.transaction([tableName], transactionMode).objectStore(tableName);
}
我可以使用此异步函数返回的事务吗?
一些相关的MDN信息:
https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API/Using_IndexedDB#Adding_data_to_the_database
重要的报价:
现在您需要进行交易,以了解其生命周期。 事务与事件循环紧密相关。如果你做一个 交易并返回事件循环而不使用它,然后 交易将变为无效。
编辑2:
还有一件事-答案是肯定的-该交易在const objectStore = await dbTransaction(DB_IMAGE, DB_OP_READWRITE)
之后可用。仅当我等待其他内容时,我才会收到TRANSACTION_INACTIVE_ERR
错误-这是有道理的。
那是设计使然吗?这是否意味着它确实在同一事件循环迭代中?
答案 0 :(得分:1)
事务仅在给定堆栈上有效。 完成一些异步工作后,即浏览器会在此处为indexedDB提供处理程序:
const db = await _dbPromise;
创建了一个新的堆栈,该堆栈一直持续到该函数结束。 但是除了主堆栈之外,还有一个微任务堆栈,并且在该堆栈上包含来自promise和观察者的所有回调。如果在执行给定堆栈中的指令时将promise标记为已解决,则在主堆栈清空后仍可立即进行调用。 (您可以将堆栈+微任务视为循环的一个“滴答声”,之后javascript将控制权传递回事件循环,以决定下一步该做什么)。
在您的示例中:
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)
})
该视频可能会清除事件循环是什么以及它如何工作:https://vimeo.com/254947206