我尝试将我的应用从使用localStorage迁移到使用indexedDB(通过Lawndart)。现在使用Futures正在弄乱我的脑袋!实际上我想要做的是:当用户想要加载已保存的游戏时,阻止应用程序继续进行,直到从indexedDB加载所有数据。这不是"在股票报价加载时显示天气......"似乎是很多例子。在我甚至可以呈现任何内容之前,我需要所有数据。
在我放弃并在我的应用程序中进行必要的点击之前,作为一个hacky意味着等待期货完成,我想做以下(使用Lawndart作为我的indexedDb的接口)并且无法包装我绕着正确的方式去做。
然而#4总会在#3完成之前尝试发生并抛出一个错误,因为它尝试在DOM中渲染的其中一个锦标赛尚未从循环中完全加载。
我想尝试新的async / await东西(会解决这个问题吗?)但我真的很想知道如何用期货/完成/ etc /等完成上述工作,因为它驱使我疯。 这是我最终得到的loadGame函数:
loadGame(String _id) {
if(_id == null) _id="a";
String _prefix;
if(_id == "a") {
_prefix = "a";
} else {
_prefix = _savedGames[_id];
}
String loadedGame;
// total # of players to load from indexedDb
int numPlayers;
// load saved game basics
_gameStore.getByKey(_prefix+"_game").then((loadedGame) {
Map saveObject = JSON.decode(loadedGame);
_year = int.parse(saveObject["year"]);
_week = int.parse(saveObject["week"]);
_numWeeks = int.parse(saveObject["numweeks"]);
numPlayers = int.parse(saveObject["numplayers"]);
}).then((_) {
// load the stored players
_players = new Map<int, Player>();
for(int i=1; i<numPlayers+1; i++) {
//note that this would go 1-by-1 loading players from indexedDb
// essentially using the Lawndart store.getByKey(_id) for each one
Player.loadFromDatabase(_prefix+"_player_"+i.toString());
}
}).then((_) {
// load the stored tournaments
_tournaments = new Map<int, Tournament>();
List<String> tournamentKeys;
for(int i=1; i<_numWeeks+1; i++) {
// this hits the database for each item
// same as for players.
// how can I ensure that all these are done before going on to next thing
// when each request to the database sends me a future?
Tournament.loadFromDatabase(_prefix+"_tournament_"+i.toString());
}
}).then((_) {
// just hides a message in the dom
hideStatus();
}).then((_) {
// this modifies the dom and shows the game status
// needs to wait till all the tournaments are loaded though or it gives me
// null pointer exceptions because the tournament it's trying to render isn't loaded yet.
nextWeek();
});
}
答案 0 :(得分:1)
我过去做过这个,不知道这是不是最好的方法,但似乎有效: -
List<Future> updateList = new List<Future>();
for(int i=1; i<_numWeeks+1; i++) {
updateList.add(Tournament.loadFromDatabase("${_prefix}${_tournament_}$i"));
}
Future.wait(updateList)..then((_) {...................
因此,您可以将所有期货存入List并等待所有这些完成后再继续。
答案 1 :(得分:1)
当你链接Future
时,你必须在Future
方法中返回then
。
例如,假设Player.loadFromDatabase
返回Future
,您应该写:
}).then((_) {
final futures = <Future>[];
// load the stored players
_players = new Map<int, Player>();
for(int i=1; i<numPlayers+1; i++) {
futures.add(Player.loadFromDatabase(_prefix+"_player_"+i.toString()));
}
return Future.wait(futures);
}).then((_) {