Хорошая @Josh уже ответил на подобный вопрос относительно сообщения об ошибке при заполнении IndexedDB ObjectStores:IndexedDB при наполнении много ObjectStores, ошибка: Не удалось выполнить «сделку» на «IDBDatabase»: Операция изменения версия работает
Failed to execute 'transaction' on 'IDBDatabase': A version change transaction is running
Ответ подходит для случая заполнения всего одного объекта ObjectStore. Однако в моем случае мне нужно заполнить не менее 5 объектов.
Я могу создать и заполнить все объекты ObjectStores, перейдя по списку, который содержит все данные, необходимые для создания и заполнения каждого из них. Скрипт отлично работает, в большинстве случаев, однако я обнаружил недостаток, поэтому вместо того, чтобы работать безупречно, каждый раз выполняется, после некоторых исполнений я получаю вышеуказанное сообщение.
Как указано в ответе, проблема связана с сроками исполнения. На основе опубликованного решения я изменил свой код, чтобы использовать ту же транзакцию во всем процессе создания и заполнения. Однако при выполнении, есть новая ошибка:
И снова @Josh это тот, кто решает.
Как я могу быстро заполнить недавно созданные объекты ObjectStores без каких-либо из предыдущих ошибок? Вот код:
var db;
function createPopulate(DB_NAME, DB_VERSION) {
const datastores = [
{osName:'a', osEndpoint:'/a', osKeyPath:'id',....},
{osName:'b', osEndpoint:'/b', osKeyPath:'id',....},
{osName:'c', osEndpoint:'/c', osKeyPath:'id',....}
];
var request = indexedDB.open(DB_NAME, DB_VERSION);
request.onupgradeneeded = function(e) {
db = this.result;
var tx = e.target.transaction;
for (i in datastores) {
// ObjectoStore created
// Index created
var customObjectStore = tx.objectStore(datastores[i].osName, "readwrite");
popTable(customObjectStore, datastores[i].osEndpoint);
}
};
Внутри функции есть popTable функция, которая получает данные и заполнит данную ObjectStore, используя функцию выборки, выборки API:
function poptable(parameter, endPoint)
fetchGet2(endPoint, populate, parameter);
function populate(json, parameter) {
for (var m in json) {
parameter.add(json[m]);
}
}
}
При запуске код, я получаю это сообщение:
DOMException: Failed to execute 'add' on 'IDBObjectStore': The transaction has finished.
Если сценарий будет изменен, чтобы выполнить popTable только OnComplete событие, сообщение об ошибке:
DOMException: Failed to execute 'objectStore' on 'IDBTransaction': The transaction has finished. at IDBTransaction.objectStore.transaction.oncomplete.
Как я могу избежать этих ошибок?
Спасибо, ваш ответ ясен, как вы думаете, используя синхронизацию, скажем, используя старый XHR? – datelligence
Это сработает, но синхронизация означает блокирование, поэтому было бы плохо для производительности. Если вы делаете все это в веб-работнике, я думаю, это может быть хорошо. Но если это возможно, было бы лучше просто не использовать другие асинхронные вещи, пока транзакция открыта. Используйте либо несколько транзакций, либо реорганизуйте свой код, чтобы другой асинхронный файл работал до начала транзакции. – dumbmatter