You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: 2-ui/5-data-storage/03-indexeddb/article.md
+36-4Lines changed: 36 additions & 4 deletions
Original file line number
Diff line number
Diff line change
@@ -250,7 +250,7 @@ The short answer is: we don't.
250
250
251
251
In the next version 3.0 of the specification, there will probably be a manual way to finish the transaction, but right now in 2.0 there isn't.
252
252
253
-
**When all transaction requests are finished, and the [microtasks queue](info:async-await#microtask-queue) is empty, it is committed automatically.**
253
+
**When all transaction requests are finished, and the [microtasks queue](info:microtask-queue) is empty, it is committed automatically.**
254
254
255
255
```smart header="What's an \"empty microtask queue\"?"
256
256
The microtask queue is explained in [another chapter](info:async-await#microtask-queue). In short, an empty microtask queue means that for all settled promises their `.then/catch/finally` handlers are executed.
@@ -431,7 +431,7 @@ So requests that return many values always return them in sorted by key order.
431
431
```
432
432
433
433
434
-
## Searching by indexes
434
+
## Searching by any field with an index
435
435
436
436
To search by other object fields, we need to create an additional data structure named "index".
437
437
@@ -643,17 +643,49 @@ try {
643
643
644
644
So we have all the sweet "plain async code" and "try..catch" stuff.
645
645
646
-
If we don't catch the error, then it falls through and finally becomes an "unhandled promise rejection" event on `window` object.
646
+
### Error handling
647
647
648
-
We can handle them like this:
648
+
If we don't catch the error, then it falls through, just as usual.
649
+
650
+
Ultimately, if uncaught, it becomes an "unhandled promise rejection" event on `window` object.
let request =event.target; // IndexedDB native request object
653
657
let error =event.reason; // Unhandled error object, same as request.error
658
+
...report about the error...
654
659
});
655
660
```
656
661
662
+
### "Inactive transaction" pitfall
663
+
664
+
As it was said, a transaction auto-commits as soon as the browser is done with the current code and microtasks.
665
+
666
+
So if we put an *macrotask* like `fetch` in the middle of a transaction, then the transaction won't wait for it to finish. It just auto-commits. So the next request in it fails.
667
+
668
+
Here's an example of `fetch` in the middle of the transaction:
669
+
670
+
```js
671
+
let transaction =db.transaction("inventory", "readwrite");
672
+
let inventory =transaction.objectStore("inventory");
The next `inventory.add` after `fetch``(*)` fails with an "inactive transaction" error, because the transaction is already committed and closed at that time.
682
+
683
+
The workaround is same as when working with native IndexedDB: either make a new transaction or just split things apart.
684
+
1. Prepare the data and fetch all that's needed first.
685
+
2. Then save in the database.
686
+
687
+
### Getting native objects
688
+
657
689
Internally, the wrapper performs a native IndexedDB request, adding `onerror/onsuccess` to it, and returns a promise that rejects/resolves with the result.
658
690
659
691
That works most fine of the time. The examples are at the lib page <https://github.com/jakearchibald/idb>.
0 commit comments