2011-10-31 59 views
0

我有與沒有執行預期的一些代碼有問題,我應該解釋一下它在做什麼第一:函數不被同步調用?

  • 在文檔加載功能selectForLists正在查詢一個SQLite數據庫 含足球比分,特別是表稱爲匹配,然後 調用函數renderLists。

  • RenderLists將演奏團隊放入排序列表中,刪除重複項 。

  • 那麼對於球隊的這個列表中的每個入口函數latestTest是 被調用,它從匹配表,其中該 球隊打得並呼籲latestTest2選擇所有行。

  • LatestTest2統計該團隊正在播放的行數,並且 向插入的div輸出一些代碼。

  • 一旦已經完成了每一支球隊應該恢復到 完成renderLists功能並調用加載的功能,除了 它不,我要添加一個延遲調用該函數,因爲 它不發生的最後一次。

我希望有人能告訴我什麼是錯誤的,爲什麼在上述所有完成後不調用加載的函數?此外,如果任何人有任何提示,以獲得更高效的代碼相同的結果,我非常希望這一點。我很確定很多人會發現代碼很糟糕,我知道有太多的函數,可能有很多更好的方法來做這件事,但它已經有幾年在javascript和uni中工作了。正在與它和sqlite掙扎。

代碼低於或http://pastebin.com/7AxXzHNB感謝

function selectForLists() { //called on (document).ready 
    db.transaction(function(tx) { 
     tx.executeSql('SELECT * FROM matches', [], renderLists); 
    }); 
} 

function renderLists(tx, rs) { 
    var playingList = new Array(); 
    for (var i = 0; i < rs.rows.length; i++) { 
     playingList.push(rs.rows.item(i)['playing']); 
    } 

    playingListSort = playingList.sort(); 
    var playingListFinal = new Array(); 

    playingListSort.forEach(function(value) { 
     if (playingListFinal.indexOf(value) == -1) { 
      playingListFinal.push(value); 
     } 
    }); 

    for (var c = 0; c < playingListFinal.length; c++) { 
     latestTest(playingListFinal[c]); 
    } 

    loaded(); //not running last in the function 
    //setTimeout(loaded,1000); 
    /////Using a delay because it doesn't run after the above has completed 
} 

function latestTest(team) { 
    db.transaction(function(tx) { 
     tx.executeSql('SELECT * FROM matches WHERE playing="' + team + '"', [], latestTest2); 
    }); 
} 

function latestTest2(tx, rs) { 
    counted = rs.rows.length; 
    var theFunction = rs.rows.item(0)['playing']; 

    $('#inserted').append('<li onclick="onToDate(\'' + theFunction + '\')"><img width="30px"  height="25px" id="popupContactClose" src="style/soccer.png"><div id="popupContactClose2">' + counted + '</div></img>' + rs.rows.item(0)['playing'] + '</li>'); 
} 
+0

此代碼是否在瀏覽器中運行?你如何直接連接到數據庫? –

+0

是的,它在瀏覽器中,另一個頁面在localstorage中創建數據庫 – mao

+0

@MattBall它是不贊成使用的Web SQL API。 – Raynos

回答

2

latestTest函數調用另一個executeSQL功能與它自己的回調。 回調將在SQL完成時執行,這將在任意時間執行。

renderLists函數將繼續正常執行(包括調用loaded函數),完全與執行latestTests中的回調有關。

你的錯誤是認爲loaded會「等待」被執行 - 你仍然會有latestTest中DB代碼的未決回調。

+0

啊我現在明白了,謝謝你的解釋。當sql完成其業務時,你能想到任何方式來調用加載嗎? – mao

+0

@mao我首先嚐試在SQL中做更多;它擅長排序和分組。您可以通過選擇所有團隊並使團隊區別於JavaScript來調用'latestTest',並從重做的'latestTest2'調用'loaded'。您可以使用[同步API](http://www.w3.org/TR/webdatabase/#synchronous-database-api),但Raynos說的可能值得關注。 –

+0

好的謝謝,這一切都有道理。我早些時候嘗試過,並且我無法將latestTest和latestTest2組合到相同的函數中。我現在會嘗試更多,現在我知道到底發生了什麼。 – mao

3

兩個db.transactiontx.executeSql是異步的功能,就像setTimeout,在那裏,如果你寫

setTimeout(function(){ 
    doLater(); 
}, 1000) 
doNow(); 

doNow()doLater()之前執行因爲你創建的回調函數會在將來某個時間被調用。

在你的情況下,latestTest()調用db.transaction,然後tx.executeSql,它們都是異步的。這意味着,回調函數latestTest2將在未來某個時間被調用,當調用loaded()時,將在之後調用

+0

是的,我之前沒有意識到數據庫/ sql函數是異步的。我想避免在加載的函數上使用時間延遲,因爲我不知道我想要調用的函數需要多長時間。在數據庫/ sql函數完成後,是否有任何事件可用於調用加載? – mao