indexedDB openCursor транзакцията onsuccess връща празен масив

            req = db.openCursor();
            req.customerData=new Array() //[{a:1}]
            req.onsuccess = function(e) {
                var cursor = e.currentTarget.result;
                if (cursor) {
                    //console.log(cursor.value);
                    e.currentTarget.customerData.push(cursor.value);
                    e.currentTarget.customerData.push("hello?");         
                    cursor.continue()
                }
                else {
                    console.log(e.currentTarget.customerData) //this always correct
                }
            }

     console.log(req.customerData); //outside the onsuccess everything is gone?

console.log(req);

Мога да видя customerData, когато отворя обекта в конзолата на Chrome

console.log(req.customerData);

Но когато направя горното, той е празен?

замяна на new Array() с [{a:1}]

console.log(req.customerData);

Виждам a, а също и другите обекти

но след това пак

console.log(req.customerData[0].a);

работи и другите обекти ги няма.

Как мога да запазя клиентски данни? Опитах просто да натисна числа или текст, но същото нещо след приключване на транзакцията. Не мога да извадя данните, да ги покажа само на console.log() по време на транзакцията?

Знам, че трябва да е нещо минало по препратка, но всяка променлива, която въвеждам, изчезва?

Добавен е пълен пример по-долу, просто въведете write() и read() в конзолата

    <script>
        var iDB
        ready=function(){
            var request = indexedDB.open("my-database",1);
            request.onupgradeneeded = function(e) {
                var db = e.currentTarget.result
                var store = db.createObjectStore("store", {keyPath: "muts", autoIncrement:false})
                //store.createIndex("by_submit", "submit", {unique: false})
                console.log('db upgrade', 'v'+db.version)
            }
            request.onerror = function(e) {
                //var db = e.currentTarget.result;
                //db.close()
                console.error('db error ',e)
            }
            request.onsuccess = function(e) {
                var db = e.currentTarget.result
                db.onversionchange = function(e) {
                    db.close()
                    console.log('db changed', 'v'+db.version, 'CLOSED')
                }
                console.log('db setup', 'v'+db.version, 'OK')
            }
            iDB=request
        }

        drop=function(){
            iDB.result.close()
            var req = indexedDB.deleteDatabase(this.iDB.result.name);
            req.onsuccess = function() {console.log("Deleted database successfully")}
            req.onerror = function() {console.log("Couldn't delete database")}
            req.onblocked = function() {console.log("Couldn't delete database due to the operation being blocked")}
        }

        read=function(){
            var db=iDB
                    .result
                    .transaction(["store"], "readwrite").objectStore("store");

            var req = db.openCursor();
            req.iData=new Array();
            req.onsuccess = function(e) {
                var cursor = e.currentTarget.result;
                if (cursor) {
                    e.currentTarget.iData.push(cursor.value);
                    e.currentTarget.iData.push("hello");
                    cursor.continue()
                }
                else {
                    console.log(e.currentTarget.iData)
                }
            }

            console.log(req.iData)

        }

        write=function(){
            var db=document.querySelector('my\-database')
                .iDB
                .result
                .transaction(["store"], "readwrite").objectStore("store");

            var customerData = [
                {muts: "Bill", qty: "1"},
                {muts: "Donna", qty: "1"}
            ]

            for (var i in customerData){db.put(customerData[i])}
        }

        ready()
    </script>

person Gert Cuykens    schedule 30.09.2014    source източник
comment
Глупав въпрос, но защо пишете данни обратно в обекта на заявката? Защо не използвате свой собствен масив? Склонен съм да третирам такива обекти на заявка като само за четене (дори и да не са).   -  person Raymond Camden    schedule 30.09.2014
comment
Бях отчаян хаха :) Опитах всичко, за да го вкарам в отделен масив. Просто искам променлива, която има данни в нея, след като курсорът е готов.   -  person Gert Cuykens    schedule 30.09.2014


Отговори (1)


Няколко неща

  • Препоръчвам да не задавате потребителски свойства на IDBRequest обект. Вместо това създавайте и осъществявайте достъп до обекти, които са във външен обхват.
  • Няма нужда да използвате event.currentTarget. event.target е достатъчен (както и „this“, както и самият обект на заявката).
  • onversionchange е отхвърлен.
  • Поради асинхронния характер на indexedDB, може да се опитвате да отпечатате нещо на конзолата, което все още не съществува или вече не съществува. Вместо това опитайте да отпечатате нещо, когато транзакцията приключи.

Например:

function populateArray(openDatabaseHandle, onCompleteCallbackFunction) {
  var transaction = openDatabaseHandle.transaction('store');
  var store = transaction.objectStore('store');
  var myArray = [];
  var request = store.openCursor();
  request.onsuccess = function() {
    var cursor = this.result;
    if(!cursor) return;
    myArray.push(cursor.value);
    cursor.continue();
  };
  transaction.oncomplete = function() {
    onCompleteCallbackFunction(myArray);
  };
}

// An example of calling the above function
var conn = indexedDB.open(...);
conn.onsuccess = function() {
  populateArray(this.result, onPopulated);
};

// An example of a callback function that can be passed to 
// the populateArray function above
function onPopulated(data) {
  console.debug(data);
  data.forEach(function(obj) {
    console.debug('Object: %o', obj);
  });
}
person Josh    schedule 30.09.2014
comment
Ще се върна към това, първо трябва да направя някои тестове, за да сравня разликата. - person Gert Cuykens; 30.09.2014
comment
Добре, ключовата част наистина е, че обхватът, където мога да използвам данните, е на oncomplete същия принцип като onload за ajax - person Gert Cuykens; 01.10.2014
comment
Създаването на масивен обект от цялото съдържание във външния обхват потенциално ще увеличи ли паметта? Тогава не дублира ли базата данни? Може ли да бъде достъпен самият курсор от мястото, където е бил извикан? - person Vass; 07.07.2021