2014-04-05 25 views
0

我試圖從索引數據庫中獲取某個鍵的值,並將它們添加到數組中,該數組在onsuccess函數內工作正常,但在其之後爲空。我通過命令猜測記錄到控制檯的兩年[0]顯示該問題與異步有關。我顯然不是真正理解事情發生的順序以及如何實現我想要的。有人可以幫助我理解問題是什麼,也可能指向正確的方向來克服它。數組填充IndexedDB對象存儲鍵的值是否全局無法訪問?

// the array I want the values in 
var years = new Array(); 

// function retrieves all objects between certain years, low and high 
function getYears(low, high){ 

var request = window.indexedDB.open("matchDB", 1); 
request.onerror = function(event) {console.log("onerror");} 

request.onsuccess = function(event) { 
var db = event.target.result; 
var objectStore = db.transaction(["matches"], 'readonly').objectStore("matches"); 

var index = objectStore.index("year"); 
var range = IDBKeyRange.bound(low, high, true, true); 

var request = index.openCursor(range); 
    request.onsuccess = function(evt) { 
    var cursor = evt.target.result; 
    if (cursor) { 
     var matchList = cursor.value; 
     // the value of the key year is pushed into the array years 
     years.push(matchList.year); 
     console.log(years[0]); // this works 
     cursor.continue(); 
    } 
    } 
console.log(years[0]); //this is undefined 
} 
} 
+1

數據庫訪問是異步的。任何依賴於結果的事情都必須在'onsuccess'函數中完成。 – Barmar

+1

這就像AJAX,所以請參閱:http://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-ajax-call – Barmar

回答

1

request.onsuccess是一個回調函數,將在異步請求完成時被調用。請注意,您只是將函數分配給onsuccess屬性,則不會執行該函數。它可以在數秒後執行。

接下來的代碼會在定義後繼續執行,所以console.log(years [0])會立即被調用,這就是爲什麼它會打印出「未定義」的原因,因爲回調方法沒有尚未執行。所有處理「年」的代碼都應該在回調中進行。

如果您不想將所有代碼都放在回調中,只需定義另一個方法並在回調方法中調用它。

function handleRequest(evt) { 
    var cursor = evt.target.result; 
    if (cursor) { 
     var matchList = cursor.value; 
     // the value of the key year is pushed into the array years 
     years.push(matchList.year); 
     console.log(years[0]); // this works 
     cursor.continue(); 
    } 
} 

var request = index.openCursor(range); 
    request.onsuccess = function(evt) { 
    handleRequest(evt); 
    } 
} 
+0

感謝您的解釋@Triad,我開始明白它。所以當我使用index.openCursor(range)時,它會多次請求,直到它匹配範圍內的所有對象?那麼我會如何在完成一次後運行一次? – mao

+0

我不太清楚openCursor方法的作用,但是當它被調用時,瀏覽器會異步地在別的地方運行它,其餘的代碼會像平常一樣繼續。所有的代碼實際上都可以完成執行,然後當方法結束時,它知道調用你指定的回調方法。它只應該被調用一次,但我不能確定沒有看到openCursor方法。編輯:它看起來像一個回調裏面的回調,這可能是它不止一次被調用的原因。 – Triad

+0

再次感謝您的解釋,我能夠在事務完成時使用transaction.oncomplete = function(){ – mao