При отладке этой ошибки полезно ознакомиться с ней.Эта ошибка является основной, общей ошибкой JavaScript, которая не распространяется только на indexedDB.Ошибка Uncaught TypeError: Cannot read property 'result' of undefined
возникает при попытке доступа к свойству неинициализированного объекта.Неинициализированный объект в этом случае - переменная request
, а свойство - result
.Поэтому понимание этой ошибки - это вопрос понимания того, почему request
не определено в тот момент, когда вы пытаетесь получить доступ к одному из его свойств.
Я не совсем уверен, почему запрос не определен, если не поиграться сэтот код в браузере сам.Тем не менее, у меня есть первое предположение, которое, возможно, поможет вам.
Вы снова объявляете ту же самую переменную позже в функции в строке var request = db.transaction...
.Это может быть причиной того, что переменная ранее не была определена в функции.Я попытаюсь объяснить, почему.
Когда вы объявляете переменную с ключевым словом var
, это не всегда происходит в том месте, где вы ее объявляете.Когда интерпретатор JavaScript оценивает ваш код, он вносит в него ряд изменений.Одно из происходящих преобразований известно как подъем .Переменные, объявленные с помощью var
, переносятся в начало функции и / или в некоторых случаях даже раньше и за пределы области действия функции.Итак, это нелогично, но то, как интерпретатор на самом деле видит ваш код, выглядит примерно так:
request.onsuccess = function(event) {
var request = undefined;
console.log(request.result);
if(request.result) {
...;
request = db.transaction...;
...;
}
};
Как вы можете видеть в этом варианте вашего кода, запрос явно не определен к тому времени, когдаВыражение console.log оценивается.
Как исправить эту ошибку?Есть несколько способов.
Во-первых, рассмотрите возможность использования let / const вместо var.let / const ограничен областью действия.Думайте о областях как об иерархии блоков {}.Если позднее вы объявите запрос как let request = ...
, то это позволит избежать проблемы с подъемом, поскольку request
не будет поднят за пределы области его действия включающего блока {} и, следовательно, никогда не поднимется в порядке оценки до начала области функционального блока предка.
Во-вторых, рассмотрите возможность использования другой переменной.Вместо того, чтобы делать var request = db.transaction...;
во второй раз, сделайте var request2 = db.transaction...;
.Теперь подъем по-прежнему происходит, но на этот раз переменная request2
поднимается в верхнюю часть функции, у которой нет конфликта идентификаторов с request
.Теперь запрос будет определен во время вызова console.log
.
В-третьих, рассмотрите возможность использования одной транзакции indexedDB.Вы можете отправить несколько запросов, используя одну транзакцию.Это не очевидно из вашего кода, но, похоже, у вас нет веских причин использовать отдельные транзакции.Единственная причина, по которой я могу придумать, - это просто незнакомство с indexedDB.Так что это поможет узнать, как выдавать несколько запросов на транзакцию.Кроме того, в случае возникновения проблемы использование одной транзакции чтения-записи, вероятно, будет быстрее, чем использование одной операции чтения с последующей одной записью, если это, возможно, послужило причиной для нескольких txns.
Когда вы используете несколько запросов наtxn, теперь вы, вероятно, заинтересуетесь, когда завершится txn, вместо того, чтобы интересоваться, когда завершатся отдельные запросы, и, следовательно, вам больше не нужно даже объявлять второй объект запроса, и, следовательно, больше не будет запускаться лицом в первую очередь.проблема подъема.
Это будет выглядеть примерно так:
var txn = db.transaction(..., 'readwrite');
txn.oncomplete = function(event) {
console.debug('txn completed');
};
txn.onerror = function(event) {
console.debug('txn failed', event.target.error);
};
var store = txn.objectStore(...);
var request = store.get(...);
request.onsuccess = function(event) {
//...;
store.put(...);
//...;
};
В случае, если это не очевидно, здесь я просто повторно использую хранилище, которое является экземпляром IDBObjectStore, которыйвсе еще привязанный к транзакции, в которой он был создан, когда я позже позвоню store.put
.
Любой из этих трех различных подходов, вероятно, решит вашу проблему.