函数在数组填充之前返回

huangapple go评论70阅读模式
英文:

Function returning before array is populated

问题

我正在尝试显示来自Firestore数据库的集合中的所有文档。以下是我查询数据库并将文档转换为可用对象的部分。

class DatabaseService {
  static List<Recipe> getSavedRecipes(String uid) {
    List<Recipe> recipes = [];
    FirebaseFirestore.instance
        .collection("users")
        .doc(uid)
        .collection('saved recipes')
        .get()
        .then(
      (querySnapshot) {
        print("成功完成");
        for (var docSnapshot in querySnapshot.docs) {
          recipes.add(Recipe.fromFirestore(docSnapshot));
        }
      },
      onError: (e) => print("完成时出错:$e"),
    );
    print(recipes);
    return recipes; // 存在竞争条件 - 由于某种原因,在数组填充之前返回
  }
}

奇怪的是,该函数在能够填充我的recipes数组之前返回,导致此打印语句

print(recipes); 什么也不返回([])

这是为什么发生这种情况的原因吗?有办法修复吗?

更新:

通过执行以下操作修复了该问题:

class DatabaseService {
  static Future<List<Recipe>> getSavedRecipes(String uid) async {
    late List<Recipe> recipes = [];
    final docs = FirebaseFirestore.instance
        .collection("users")
        .doc(uid)
        .collection('saved recipes')
        .get();

    await docs.then(
      (querySnapshot) {
        print("成功完成");
        for (var docSnapshot in querySnapshot.docs) {
          recipes.add(Recipe.fromFirestore(docSnapshot));
        }
      },
      onError: (e) => print("完成时出错:$e"),
    );

    return recipes;
  }
}
英文:

I am trying to display all the documents in a collection from my Firestore database. Here is where I query the DB and turn the documents into usable objects.

class DatabaseService {
  static List&lt;Recipe&gt; getSavedRecipes(String uid) {
    List&lt;Recipe&gt; recipes = [];
    FirebaseFirestore.instance
        .collection(&quot;users&quot;)
        .doc(uid)
        .collection(&#39;saved recipes&#39;)
        .get()
        .then(
      (querySnapshot) {
        print(&quot;Successfully completed&quot;);
        for (var docSnapshot in querySnapshot.docs) {
          recipes.add(Recipe.fromFirestore(docSnapshot));
        }
      },
      onError: (e) =&gt; print(&quot;Error completing: $e&quot;),
    );
    print(recipes);
    return recipes; //race condition here - for some reason it is returning before the array is populated
  }
}

Oddly enough, the function is returning before it is able populate my recipes array, making this print statement

print(recipes); return nothing ([])

Is there a reason why this is happening? Any way to fix it?

UPDATE :

Fixed the issue by doing this:

class DatabaseService {
  static Future&lt;List&lt;Recipe&gt;&gt; getSavedRecipes(String uid) async {
    late List&lt;Recipe&gt; recipes = [];
    final docs = FirebaseFirestore.instance
        .collection(&quot;users&quot;)
        .doc(uid)
        .collection(&#39;saved recipes&#39;)
        .get();

    await docs.then(
      (querySnapshot) {
        print(&quot;Successfully completed&quot;);
        for (var docSnapshot in querySnapshot.docs) {
          recipes.add(Recipe.fromFirestore(docSnapshot));
        }
      },
      onError: (e) =&gt; print(&quot;Error completing: $e&quot;),
    );

    return recipes;
  }
}

答案1

得分: 1

这是因为.then()内部的方法在get()方法返回的Future完成时被调用。这是异步发生的,而且你的代码中没有任何东西阻止代码执行到return recipes语句。

尝试将你的代码转换为异步方法。尝试以下方式,如果有效请告诉我(未经测试,可能存在语法错误):

class DatabaseService {
  static Future<List<Recipe>> getSavedRecipes(String uid) async {
    List<Recipe> recipes = [];
    final querySnapshot = await FirebaseFirestore.instance
        .collection("users")
        .doc(uid)
        .collection('saved recipes')
        .get();

    for (var docSnapshot in querySnapshot.docs) {
      recipes.add(Recipe.fromFirestore(docSnapshot));
    }

    print(recipes);
    return recipes; // 这里可能存在竞争条件 - 有些情况下它会在数组填充之前返回
  }
}
英文:

This occurs because the method inside .then() is called whenever the Future from the get() method finishes. This occurs asynchronously and there's nothing in your code that's stopping the code from reaching the return recipes statement.

Try converting your code to an asynchronous method. Try the following and let me know if it works (not tested, there may be syntax errors):

class DatabaseService {
  static List&lt;Recipe&gt; getSavedRecipes(String uid) async {
    List&lt;Recipe&gt; recipes = [];
    final querySnapshot = await FirebaseFirestore.instance
        .collection(&quot;users&quot;)
        .doc(uid)
        .collection(&#39;saved recipes&#39;)
        .get();

    for (var docSnapshot in querySnapshot.docs) {
      recipes.add(Recipe.fromFirestore(docSnapshot));
    }

    print(recipes);
    return recipes; //race condition here - for some reason it is returning before the array is populated
  }
}

huangapple
  • 本文由 发表于 2023年3月4日 03:24:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/75631132.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定