【问题标题】:Calling multiple APIs slows down the app to load?调用多个 API 会减慢应用的加载速度?
【发布时间】:2019-10-18 09:47:24
【问题描述】:

所以我使用互联网上可用的 API 制作了一个新闻应用程序。所以我不得不为每个不同的类别使用不同的 API。有超过 9 个类别,所以这使我的应用程序加载非常缓慢。那么,解决这个问题的方法是什么。加载应用程序一段时间后,我如何才能仅在初始状态下调用 2 个 API,而在其他状态下调用其他 API。 请看下面的代码:

class NewsCard extends StatefulWidget {
  @override
  _NewsCardState createState() => _NewsCardState();
}

class _NewsCardState extends State<NewsCard>
    with SingleTickerProviderStateMixin {

  TabController tabController;
  static DateTime now = DateTime.now();
  String formattedDate;
  List newsData;
  List topNews1;
  List businessNews1;
  List worldNews1;
  List sportsNews1;
  List entertainmentNews1;
  List educationNews1;
  List tvnews1;
  List electionNews1;
  List lifeNews1;
  bool isLoading = true;
  final String toi= "https://timesofindia.indiatimes.com/";
  final String topNews =
      "API url";
  final String sportsNews =
      "API url";

  final String businessNews =
      "API url";

  final String worldNews =
      "API url ";
  final String entertainmentNews =
      "API url ";
  final String educationNews =
      "API url";
  final String tvNews =
      "API url ";
  final String electionNews =
      "API url";
  final String lifeNews =
      "API url";

  final String url =
      "https://newsapi.org/v2/top-headlines?sources=google-news-in&apiKey=";

  Future getData() async {
    var response = await http.get(
      Uri.encodeFull(url),
      headers: {
        HttpHeaders.authorizationHeader: ""
      },
    );
    var response1 = await http.get(
      Uri.encodeFull(topNews),
    );
    var response2 = await http.get(
      Uri.encodeFull(businessNews),
    );
    var response3 = await http.get(
      Uri.encodeFull(worldNews),
    );
    var response4 = await http.get(
      Uri.encodeFull(sportsNews),
    );
    var response5 = await http.get(
      Uri.encodeFull(entertainmentNews),
    );
    var response6 = await http.get(
      Uri.encodeFull(tvNews),
    );
    var response7 = await http.get(
      Uri.encodeFull(lifeNews),
    );
    var response8 = await http.get(
      Uri.encodeFull(electionNews),
    );
    var response9 = await http.get(
      Uri.encodeFull(educationNews),
    );
    List data = jsonDecode(response.body)['articles'];
    List topNewsData = jsonDecode(response1.body)['stories'];
    List businessNewsData = jsonDecode(response2.body)['items'][0]['stories'];
    List worldNewsData = jsonDecode(response3.body)['items'][0]['stories'];
    List sportsNewsData = jsonDecode(response4.body)['items'][0]['stories'];
    List entertainmentNewsData = jsonDecode(response5.body)['items'][0]['stories'];
    List tvNewsData = jsonDecode(response6.body)['items'][0]['stories'];
    List lifeNewsData = jsonDecode(response7.body)['items'][0]['stories'];
    List electionsNewsData = jsonDecode(response8.body)['items'][0]['stories'];
    List educationNewsData = jsonDecode(response9.body)['items'][0]['stories'];
    setState(() {
      newsData = data;
      topNews1 = topNewsData;
      businessNews1 = businessNewsData;
      worldNews1 = worldNewsData;
      sportsNews1 = sportsNewsData;
      entertainmentNews1 = entertainmentNewsData;
      tvnews1 = tvNewsData;
      lifeNews1=lifeNewsData;
      electionNews1 = electionsNewsData;
      educationNews1  = educationNewsData;
      isLoading = false; //this is for the initial loading, this is taking too much of time.
    });
  }

  @override
  void initState() {
    super.initState();
    this.getData();
    tabController = TabController(vsync: this, length: 9);
  }

脚手架内

isLoading
                ?Column(....):Column(.....)

请记住,我是 Flutter 的初学者,所以如果我的方法是错误的,请请求我做完美的方法。

【问题讨论】:

    标签: api flutter dart


    【解决方案1】:

    由于不同的 api 调用之间没有依赖关系(api 调用 1 不需要等待 api 调用 0 完成),最好将它们全部启动并等待结果。所以不要在每个 api 调用中使用await。而是使用Future.wait 来等待最后的所有期货。比如:

      Future getData() async {
        List<Future> responseFutures = [
          http.get(
            Uri.encodeFull(url),
            headers: {HttpHeaders.authorizationHeader: ""},
          ),
          http.get(
            Uri.encodeFull(topNews),
          ),
          http.get(
            Uri.encodeFull(businessNews),
          ),
          http.get(
            Uri.encodeFull(worldNews),
          ),
          http.get(
            Uri.encodeFull(sportsNews),
          ),
          http.get(
            Uri.encodeFull(entertainmentNews),
          ),
          http.get(
            Uri.encodeFull(tvNews),
          ),
          http.get(
            Uri.encodeFull(lifeNews),
          ),
          http.get(
            Uri.encodeFull(electionNews),
          ),
          http.get(
            Uri.encodeFull(educationNews),
          ),
        ];
        List responses = await Future.wait(responseFutures);
    
        List data = jsonDecode(responses[0].body)['articles'];
        List topNewsData = jsonDecode(responses[1].body)['stories'];
        List businessNewsData = jsonDecode(responses[2].body)['items'][0]['stories'];
        List worldNewsData = jsonDecode(responses[3].body)['items'][0]['stories'];
        List sportsNewsData = jsonDecode(responses[4].body)['items'][0]['stories'];
        List entertainmentNewsData = jsonDecode(responses[5].body)['items'][0]['stories'];
        List tvNewsData = jsonDecode(responses[6].body)['items'][0]['stories'];
        List lifeNewsData = jsonDecode(responses[7].body)['items'][0]['stories'];
        List electionsNewsData = jsonDecode(responses[8].body)['items'][0]['stories'];
        List educationNewsData = jsonDecode(responses[9].body)['items'][0]['stories'];
        setState(() {
          newsData = data;
          topNews1 = topNewsData;
          businessNews1 = businessNewsData;
          worldNews1 = worldNewsData;
          sportsNews1 = sportsNewsData;
          entertainmentNews1 = entertainmentNewsData;
          tvnews1 = tvNewsData;
          lifeNews1 = lifeNewsData;
          electionNews1 = electionsNewsData;
          educationNews1 = educationNewsData;
          isLoading = false; //this is for the initial loading, this is taking too much of time.
        });
      }
    
    

    【讨论】:

    • 那么我应该用 await 删除 future 并改用 future.wait 吗?
    • 我没听懂你。我的观点是不要等待上一次通话完成(不要使用await)来开始下一次通话。全部启动一次,使用Future.wait 等待所有期货结束。检查提到的链接中的Future.wait 文档。我还添加了显式类型以使其更具可读性。
    • 这个错误来了:在初始化器中只能访问静态成员
    • 以上代码仍应在getData() 函数中。我刚刚重构了你应该如何进行 api 调用。
    • 所以我应该从 getData() 中删除异步?
    猜你喜欢
    • 2021-05-13
    • 2023-03-30
    • 2021-05-01
    • 1970-01-01
    • 2023-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多