Flutter 中 MultiMethods 的多线程

Multithreading for MultiMethods in Flutter

请问如何在 dart 中对某些函数进行多线程处理 例如我有 16 个 Future 函数 我想先 在第一个线程中执行这个函数

await GetRoot(); //Future<void>

然后第一个线程结束后我想在第二个线程中执行这些函数-同时-

 await GetLocalRadio();//Future<void>
  await GetMusic();//Future<void>
  await GetTalk();//Future<void>
  await GetSports();//Future<void>
  await GetByLocation();//Future<void>
  await GetByLanguage();//Future<void>
  await GetPodcasts();//Future<void>

然后第二个线程完成后,我想在下一个线程[=]中同时执行这些线程一起 15=]

 await GetPodcasts2();//Future<void>
  await GetByLocation2();//Future<void>

然后当第二个线程结束时我想当第三个函数完成时执行这些函数同时在一个新话题

  await FillPdcasts();//Future<void>
  await FillLocalRadio();//Future<void>
  await FillMusic();//Future<void>
  await FillTalk();//Future<void>
  await FillSports();//Future<void>
  await FillByLocation();//Future<void>

这里是我所有方法的简单内容

 Future<void> FillByLocation()
  async {
    for (var entry in xByLocation2) {
        final responseFinalByLocation2 = await http.Client().get(entry.split('^')[1], headers: {'Content-Type': 'application/json; charset=utf-8'});
        try{
          final FinalByLocation2final = allInfosFromJson(utf8.decode(responseFinalByLocation2.bodyBytes));
          for (int i = 0; i < FinalByLocation2final.body.length; i++) {
            for (int j = 0; j < FinalByLocation2final.body[i].children.length; j++) {
              if(FinalByLocation2final.body[i].children[j].text != null && FinalByLocation2final.body[i].children[j].image != null)
              {
                if(!xListFinalAllInfos.contains(FinalByLocation2final.body[i].children[j].text + "^" + FinalByLocation2final.body[i].children[j].subtext + "^" + FinalByLocation2final.body[i].children[j].nowPlayingId + "^" + FinalByLocation2final.body[i].children[j].currentTrack+ "^" + FinalByLocation2final.body[i].children[j].url+ "^" + FinalByLocation2final.body[i].children[j].image))
                  {
                    setState(() {
                      xListFinalAllInfos.add(FinalByLocation2final.body[i].children[j].text + "^" + FinalByLocation2final.body[i].children[j].subtext + "^" + FinalByLocation2final.body[i].children[j].nowPlayingId + "^" + FinalByLocation2final.body[i].children[j].currentTrack+ "^" + FinalByLocation2final.body[i].children[j].url+ "^" + FinalByLocation2final.body[i].children[j].image);
                      // ListFinalAllInfos.putIfAbsent(
                      //     FinalByLocation2final.body[i].children[j].text, () =>
                      // FinalByLocation2final.body[i].children[j].image );
                    });
                  }
              }
            }
          }
        }catch(e){}
      }
  }

因为当我执行所有功能并等待所有功能时,这将花费大约 30 秒。 这是很多时间,所以我需要把时间控制在 30 秒以内。

这里不能选择多线程。坚持使用异步。

您所有的 await 都使您的代码变慢了。您正在强制上一个功能在下一个功能甚至可以开始之前完成。同时调用它们并使用 Future.wait.

await GetRoot();

List<Future<void>> toWait = [];
toWait.add(GetLocalRadio());
toWait.add(GetMusic());
...

await Future.wait(toWait);
toWait.clear();

toWait.add(GetPodcasts2());
toWait.add(GetByLocation2());

await Future.wait(toWait);
toWait.clear();

toWait.add(FillPdcasts());
toWait.add(FillLocalRadio());
...

await Future.wait(toWait);
toWait.clear();

此外,您在这些功能中所做的工作也执行得很低效。在处理来自调用的数据并开始下一个调用之前,您正在等待每个 http 调用完成。这可以提高效率。

以下代码使用 .then 为每个网络调用注册回调,将未来存储到列表中,并在最后使用 Future.wait 以确保它们全部完成包装函数 returns.

 Future<void> FillByLocation()
  async {
    List<Future<void>> toWait = [];
    for (var entry in xByLocation2) {
        toWait.add(http.Client().get(entry.split('^')[1], headers: {'Content-Type': 'application/json; charset=utf-8'}).then((responseFinalByLocation2){
        try{
          final FinalByLocation2final = allInfosFromJson(utf8.decode(responseFinalByLocation2.bodyBytes));
          for (int i = 0; i < FinalByLocation2final.body.length; i++) {
            for (int j = 0; j < FinalByLocation2final.body[i].children.length; j++) {
              if(FinalByLocation2final.body[i].children[j].text != null && FinalByLocation2final.body[i].children[j].image != null)
              {
                if(!xListFinalAllInfos.contains(FinalByLocation2final.body[i].children[j].text + "^" + FinalByLocation2final.body[i].children[j].subtext + "^" + FinalByLocation2final.body[i].children[j].nowPlayingId + "^" + FinalByLocation2final.body[i].children[j].currentTrack+ "^" + FinalByLocation2final.body[i].children[j].url+ "^" + FinalByLocation2final.body[i].children[j].image))
                  {
                    setState(() {
                      xListFinalAllInfos.add(FinalByLocation2final.body[i].children[j].text + "^" + FinalByLocation2final.body[i].children[j].subtext + "^" + FinalByLocation2final.body[i].children[j].nowPlayingId + "^" + FinalByLocation2final.body[i].children[j].currentTrack+ "^" + FinalByLocation2final.body[i].children[j].url+ "^" + FinalByLocation2final.body[i].children[j].image);
                      // ListFinalAllInfos.putIfAbsent(
                      //     FinalByLocation2final.body[i].children[j].text, () =>
                      // FinalByLocation2final.body[i].children[j].image );
                    });
                  }
              }
            }
          }
        }catch(e){}
        }));
      }
    await Future.wait(toWait);
  }