2011-10-31 35 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