dexie / Dexie.js

A Minimalistic Wrapper for IndexedDB
https://dexie.org
Apache License 2.0
11.58k stars 642 forks source link

Can I use a `for await...` loop inside a transaction? #1786

Closed secondl1ght closed 1 year ago

secondl1ght commented 1 year ago

I see in the Transactions docs there is a warning about using other async APIs within a Transaction https://dexie.org/docs/Dexie/Dexie.transaction()#the-auto-commit-behavior-of-indexeddb-transactions. Does this also apply to a for await loop where the async function is not an external API but a Dexie action itself?

Here is an example:

await db.transaction('rw', db.test, async () => {
  const test = await db.test.bulkGet(keys)

  for await (const t of test) {
    // do some things...

    await db.test.put(t)

    // do something else...
  }
}

Or maybe it is not neccesary to await these Dexie actions inside a Transaction because the Transaction will wait for any DB actions within the Transaction scope to resolve or reject their Promises before finishing the Transaction? If that's the case I could use a regular forEach loop on the Array and trigger a Dexie action for each record that way instead?

secondl1ght commented 1 year ago

I see now in the docs that this example is similar to what I am trying to acheive except it uses Promise.all: https://dexie.org/docs/Dexie/Dexie.transaction()#the-auto-commit-behavior-of-indexeddb-transactions. So I think I am OK to use the above code example in my post or use the Promise.all method from the docs because that way the Transaction will complete sooner I think.

secondl1ght commented 1 year ago

I think I answered my own question, please let me know if anything I assumed is incorrect. :)

dfahlander commented 1 year ago

There's no a need to use for await since Dexie API's don't return async iterables. You can await things in normal for...of loops though!

await db.transaction('rw', db.test, async () => {
  const test = await db.test.bulkGet(keys); // test will be a normal array.

  for (const t of test) { // no need to for await of normal array
    // do some things...

    await db.test.put(t)

    // do something else...
  }
}