【问题标题】:Flutter method complete before triggering another method [duplicate]在触发另一种方法之前完成颤振方法[重复]
【发布时间】:2021-03-25 06:41:15
【问题描述】:

我目前有一个 getReviewsLength() 方法,它将从 firestore 获取 _favourites 列表中每个项目的评论长度。但是,在将长度添加到 reviewsLength 列表之前,该方法已经触发了 loadingComplete() 方法。有没有办法确保 getReviewsLength() 方法在触发 loadingComplete() 之前完成?

我尝试过使用 async/await,但我似乎无法让它工作,因为我不确定该放在哪里。

getReviewsLength() {
    _favourites.forEach((shopname)  {
      firestore.collection('shops').doc(shopname['shopName']).collection('reviews').get()
          .then((value) {
          setState(() {
            int length = value.size;
            reviewsLength.add(length);
          });
      });
    });
    loadingComplete();
  }

  loadingComplete(){
    setState(() {
      loading = false;
    });
    print(reviewsLength);
  }

【问题讨论】:

  • getReviewsLength() 需要异步。您需要删除 forEach 并使用常规循环,然后等待每次调用 firestore.collection(...)
  • 谢谢@smac89。 for 循环有效!

标签: flutter dart


【解决方案1】:

await 让您控制执行顺序并适合您的特定场景:

Future<void> getReviewsLength() async {
    Future.forEach(_favourites, (shopname) async {
         dynamic value = await firestore.collection('shops').doc(shopname['shopName']).collection('reviews').get();
          setState(() {
            int length = value.size;
            reviewsLength.add(length);
          });
    });
    loadingComplete();
    return;
}

void loadingComplete() {
 setState(() {
   loading = false;
 });
 print(reviewsLength);
}

【讨论】:

  • forEach doesn't work 与您的思维方式异步。 OP 需要使用常规的 for 循环
  • 您好,感谢您的帮助。但是,它仍然打印一个空列表。我/颤振(13575):[]
  • 已更正代码以解决您提出的问题
  • 如@smac89 所述,for 循环有效!谢谢!
【解决方案2】:

是的,让你异步会在这里有所帮助

要使函数异步,您需要在函数中的(){} 之间使用关键字async,并在运行代码的地方使用await 关键字

getReviewsLength() async {
    _favourites.forEach((shopname)  {
      await firestore.collection('shops').doc(shopname['shopName']).collection('reviews').get()
          .then((value) {
          setState(() {
            int length = value.size;
            reviewsLength.add(length);
          });
      });
    });
    loadingComplete();
  }

  loadingComplete(){
    setState(() {
      loading = false;
    });
    print(reviewsLength);
  }

我不知道上面的代码是否有效,因为我不确定firestore,但一个基本的例子是

function() async {
    await print('hello');
    print('world');
}

在这里应用程序不会打印world,直到它打印hello,显然这里没有使用异步函数,但在API请求的情况下它可以使用,在你的情况下也是如此。

因此,您需要在发出请求的正确位置使用 await 关键字或将其添加到 reviewsLength

问候,

肉山

【讨论】:

    【解决方案3】:

    正如@smac89 所提到的,我改成了一个 for 循环,它可以工作了。

    Future<void> getReviewsLength() async {
        for (var shopname in _favourites) {
          dynamic snapshot = await firestore.collection('shops').doc(shopname['shopName']).collection('reviews').get();
              setState(() {
                int length = snapshot.size;//value.size;
                reviewsLength.add(length);
    
              });
        }
        loadingComplete();
        return;
      }
    
      void loadingComplete(){
        setState(() {
          loading = false;
        });
        print(reviewsLength);
      }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-12-07
      • 2012-07-10
      • 1970-01-01
      • 1970-01-01
      • 2021-03-28
      • 2011-10-11
      • 1970-01-01
      相关资源
      最近更新 更多