События DBOpenRequest не срабатывают

Я борюсь с открытием индексированной БД. Вот мой код:

var db;

window.onload = function() {

    window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
    var DBOpenRequest = window.indexedDB.open("test", 1);

    DBOpenRequest.onerror = function(event) {
        console.log("DBOpenRequest.onerror");
    };

    DBOpenRequest.onsuccess = function(event) {
        console.log("DBOpenRequest.onsuccess");
        db = DBOpenRequest.result;
    };

    DBOpenRequest.onupgradeneeded = function(event) {
        console.log("DBOpenRequest.onupgradeneeded");
    };
};

но ни одно событие не загорелось. Все свойства DBOpenRequest имеют значение null, за исключением свойства readyState, для которого установлено значение «готово», а результат — объект IDBDatabase.

Чего здесь не хватает, чтобы я мог получить доступ к indexdb через переменную db?


person Giedrius.S    schedule 27.01.2015    source источник


Ответы (2)


  1. Вам не нужно ждать, пока браузер запустит событие загрузки. Готовность indexedDB не связана с готовностью DOM. Вы можете просто вызвать indexedDB.open в глобальной области видимости, и в конечном итоге он будет выполнен.

  2. Вам, вероятно, не нужен оператор, в котором вы проверяете префиксы поставщиков. Префиксы обычно отбрасываются. Просто используйте window.indexedDB и удалите этот оператор.

  3. Вы также должны прослушивать заблокированное событие. Это событие обычно срабатывает при открытии одной и той же страницы на нескольких вкладках примерно в одно и то же время. При блокировке другие события не срабатывают.

  4. Строка db = DBOpenRequest.result, по-видимому, присваивает значение (экземпляр объекта IDBDatabase), которое допустимо только в пределах области действия функции, для переменной, определенной во внешней области, где оно больше недействительно. Это свидетельствует об отсутствии опыта написания и использования асинхронного кода. Возможно, вам следует больше узнать об асинхронном коде, прежде чем продолжить.

person Josh    schedule 27.01.2015
comment
Вы уверены в пункте 4? Копирование экземпляра db из обработчика onsuccess — это то, что я делал раньше с IDB без проблем. Я использовал значение события, хотя и не DBOpenRequest, но разве оно не должно работать нормально? - person Raymond Camden; 28.01.2015
comment
Я уверен насчет 4. Иногда это будет работать нормально, но не всегда, и это запах кода. По сути, вы эксплуатируете и рискуете, когда делаете это. Это приемлемый риск, но только в том случае, если вы знаете, что делаете, и можете отладить проблемы, которые это в конечном итоге вызовет. Я предполагаю, что кто-то, задающий такой вопрос, не может и не может. - person Josh; 28.01.2015
comment
Итак, позвольте мне спросить вас об этом - как вы справляетесь с выполнением запросов ad hoq позже? Вы помещаете все эти вызовы в обработчик onsuccess? Как вы работаете с БД глобально? - person Raymond Camden; 29.01.2015
comment
Кроме того, есть ли у вас доказательства (может быть, в спецификации?), что объект db, возвращенный в onsuccess, нельзя использовать снова? Как я уже сказал - у меня никогда не было проблем с этим. Я тоже не уверен, как это запах кода, но мы можем не согласиться с этим. - person Raymond Camden; 29.01.2015
comment
Вероятно, выходит за рамки вопроса, и снова будет длинный ответ. Вкратце, я открываю соединение по мере необходимости для выполнения последующих запросов. Все вызовы находятся внутри каждого обработчика успешного соединения. Я не использую глобальную переменную БД. В спецификации (w3.org/TR/IndexedDB) indexedDB.open является асинхронным. - person Josh; 29.01.2015
comment
Тот факт, что .open является асинхронным, не означает, что мы не можем сохранить дескриптор базы данных позже. Я не уверен, что вы правы, но, как вы сказали, мы выходим за рамки. - person Raymond Camden; 29.01.2015
comment
Джош, для справки, я разместил это в группе Google IDB. Это сверхмалый объем, но я решил, что это будет лучшее место для обсуждения. - person Raymond Camden; 29.01.2015

Ну, во-первых, в случае успеха БД исходит из события, а не из исходного объекта:

db = event.target.result;

Скорее всего, вы получили это как ошибку в вашей консоли.

person Raymond Camden    schedule 27.01.2015
comment
event.target.result === DBOpenRequest.result - person Josh; 27.01.2015
comment
О, интересно - спасибо. Не знал, что он обновил исходный объект запроса, но это имеет смысл. - person Raymond Camden; 28.01.2015