颤振异步编程

时间:2019-11-19 20:58:14

标签: asynchronous firebase-realtime-database flutter dart

使用 数据集后,我想检查未使用的数据集的数量。如果我超过阈值,我想获取新数据。

useQuestion(Question question) async {
    print("using question $question");
    question.used=1;
    final db = await database;
    int count = await db.rawUpdate(
    'UPDATE Question SET used = ? WHERE question = ?',
    [question.used,question.question]);
    print(question);
    print("Made $count changes");
    var questions = await _checkQuestionThreshold();
    print(questions);
    for (var q in questions) {
        newQuestion(Question.fromJson(q));
      }
  }

检查阈值

_checkQuestionThreshold() async {
print("count questions...");
final db = await database;
var res = await db.query("Question");
int count = Sqflite.firstIntValue(
    await db.rawQuery('SELECT COUNT(*) FROM Question'));
int countUsed = Sqflite.firstIntValue(
    await db.rawQuery('SELECT COUNT(*) FROM Question where used="1"'));
int i = 0;
if (count < 1 || (countUsed / count) < 0.5) {
  print("Okay... we fetch new...");



  return await _fetchFromFirebase();
}

从数据库获取:

_fetchFromFirebase() async {
    var questionJson;
     databaseReference.once().then((DataSnapshot snapshot) async {
        questionJson = await snapshot.value;
      }).catchError((e) {
        print(e);
      });
      return questionJson;
  }

但是,调用for (var q in questions) { newQuestion(Question.fromJson(q)); }时出现以下错误,我想知道我到底缺少什么。

I/flutter ( 5150): count questions...
I/flutter ( 5150): Okay... we fetch new...
I/flutter ( 5150): null
E/flutter ( 5150): [ERROR:flutter/lib/ui/ui_dart_state.cc(148)] Unhandled Exception: NoSuchMethodError: The getter 'iterator' was called on null.
E/flutter ( 5150): Receiver: null

1 个答案:

答案 0 :(得分:1)

您的问题是questions为null,因此尝试对其进行迭代将引发错误。

查看您的代码,错误的根源似乎来自您的_fetchFromFirebase方法。在这种情况下,您调用databaseReference.once(),然后在then部分中将结果分配给questionJson。但是,您永远不会await进行此调用,因此_fetchFromFirebase方法最终会在调用后立即返回questionJson的值,而无需等待其完成。届时,questionJson将为null,这就是返回的内容。

通常,我建议不要将Future.then.catchError模式与async/await模式混合使用,因为这会导致隐藏实际情况的逻辑混乱。因此,我建议像这样仅坚持async/await

_fetchFromFirebase() async {
  try {
    final snapshot = await databaseReference.once();
    final questionJson = await snapshot.value;
    return questionJson;
  } catch (e) {
    print(e);
    return null;
  }
}