当有大量数据从IndexedDB中提取时,如何阻止Dart应用程序向前移动而你所得到的只是期货?

时间:2014-12-19 04:30:32

标签: dart indexeddb dart-async

我尝试将我的应用从使用localStorage迁移到使用indexedDB(通过Lawndart)。现在使用Futures正在弄乱我的脑袋!实际上我想要做的是:当用户想要加载已保存的游戏时,阻止应用程序继续进行,直到从indexedDB加载所有数据。这不是"在股票报价加载时显示天气......"似乎是很多例子。在我甚至可以呈现任何内容之前,我需要所有数据。

在我放弃并在我的应用程序中进行必要的点击之前,作为一个hacky意味着等待期货完成,我想做以下(使用Lawndart作为我的indexedDb的接口)并且无法包装我绕着正确的方式去做。

  1. 加载已保存的游戏状态。
  2. 从游戏中加载已保存的玩家数据(300名玩家)
  3. 从游戏中加载已保存的锦标赛数据(40多个锦标赛,逐个加载和创建对象,也可以使用流批量尝试。)
  4. 使用已保存状态的锦标赛显示刷新DOM。
  5. 然而#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();
      });
    }
    

2 个答案:

答案 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((_) {