Flutter Dart:Future.wait()通过引用传递值吗?

时间:2018-11-28 01:59:27

标签: dart flutter

在以下情况下,如何通过引用传递变量List<Document> itemList

Future.wait([futDocs]).then((dataRet){
  dataRet.forEach((doco) {
    var docList = doco.documents;
    docList.forEach((doc){
      var docTitle = doc['title'];
      print("data is $docTitle");
      itemList.add(docTitle); <--- change not reflected outside this function

在上述Future.wait()中执行itemList时,itemList.add(docTitle)不会改变。我相信原因是因为itemList没有通过引用传递。如果我无法通过引用传递itemList,该如何做?我可以返回dataRet作为列表并在Future.wait()之外使用它吗?

添加更多信息...

上面的调用在class ListBuilder的构造函数中执行,如以下代码所示:

class ListBuilder {
 List<Document> itemList = new List<Document>();

 ListBuilder(){
   var futDocs = Firestore.instance.collection('Data').orderBy('time').limit(10).getDocuments();

   Future.wait([futDocs]).then((dataRet) {
     dataRet.forEach((doco) {
       var docList = doco.documents;
       docList.forEach((doc){
         var docTitle = doc['title'];
         print("data is $docTitle");
         itemList.add(docTitle); <--- change not reflected outside this function

  [...]

在等待答案的同时,我尝试了自定义设置方法和获取方法以及this.itemList.add(...)的使用,但均未成功。

任何帮助,我们将不胜感激。 预先感谢!

3 个答案:

答案 0 :(得分:0)

更多代码可能会有所帮助,但是首先想到的是这些:

  1. 在您的await之前调用Future.wait可能会起作用,以确保异步代码可以正常运行

  2. 这似乎不太可能,但是将您添加到列表中时,您可能必须致电setState

编辑:

我建议这样的代码:

class ListBuilder { 
  List<Document> itemList = new List<Document>();        

  Future<void> myFunc(var futDocs) async {
    await Future.wait([futDocs]).then((dataRet){  
    [...] *Rest of your Future code here*
  }

  ListBuilder() {
   var futDocs = Firestore.instance.collection('Data').orderBy('time').limit(10).getDocuments(); 

   myFunc(futDocs)

  [...]

答案 1 :(得分:0)

Dart中的所有对象均通过引用传递。 问题可能是[itemList]不会立即更新,因为Future.wait是一个异步函数。任何处理itemList的代码都必须在回调函数(.then((dataret) { ... });内运行。

class ListBuilder {
    List<Document> itemList = new List<Document>();

    ListBuilder() {
    var Docs = 
    Firestore.instance.collection('Data').orderBy('time').limit(10).getDocuments();

    Future.wait([futDocs]).then((dataRet) {
        dataRet.forEach((doco) {
            var docList = doco.documents;
            docList.forEach((doc) {
                var docTitle = doc['title'];
                itemList.add(docTitle);
            });      
        });
        /* 
           itemList has been updated here because we are inside a callback function that 
           runs _after_ Future.wait has completed.
        */
    });
    /*
       itemList hasn't been updated here _yet_ because this code runs immediately, 
       regardless how long the Future.wait call takes to complete.           
    */
    }    
}

如果需要,可以使用异步/等待逻辑代替回调函数,该函数通常更易于阅读和维护。此处更多信息:https://www.dartlang.org/tutorials/language/futures

答案 2 :(得分:0)

我已经解决了问题,但是它与通过引用传递值无关。谢谢您的回答,他们实际上使我思考并为我指明了正确的方向。 以下是解决上述问题的方法:D LOL

Tl; dr;答案:

更改窗口小部件以使用streamBuilder

好答案

问题是由于对列表所做的更改未反映在.then()函数之外。嗯,问题本身与列表如何传递给函数无关,而是与异步/等待逻辑的使用有关。执行该应用程序后,它将使用列表中的当前项目填充itemList中的Widget-启动时为空。同时,通过异步调用,firebase获取数据并更新列表。但是,UI不变。现在,setState给了我一个主意,但不是解决方案。就我而言,我不需要有状态的小部件,而是在小部件的创建过程中使用StreamBuilder。这使用stream

将列表绑定到异步调用
new StreamBuilder(
  stream: Firestore.instance.collection('data').orderBy('time').limit(10).snapshots(),
          builder: (context, snapshot) {
            return itemList...

再次感谢!