Flutter 异步编程

Posted

技术标签:

【中文标题】Flutter 异步编程【英文标题】:Flutter async programming 【发布时间】:2020-03-15 11:35:22 【问题描述】:

使用一个数据集后,我想检查有多少数据集未使用。如果超过阈值,我想获取新数据。

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】:

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

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

一般来说,我建议不要将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;
  

【讨论】:

以上是关于Flutter 异步编程的主要内容,如果未能解决你的问题,请参考以下文章

Flutter异步编程详解

Flutter异步编程 http网络请求数据

在 Dart 和 Flutter 中探索异步编程

FlutterFuture 与 FutureBuilder 异步编程代码示例 ( FutureBuilder 构造函数设置 | 处理 Flutter 中文乱码 | 完整代码示例 )

flutter入门之dart中的并发编程异步和事件驱动详解

flutter入门之dart中的并发编程异步和事件驱动详解