一尘不染

异步/等待/然后在Dart / Flutter中

flutter

我有一个Flutter应用程序,正在使用SQFLITE插件从SQLite DB中获取数据。在这里,我面临一个奇怪的问题。据我了解,我们使用async /
await或then()函数进行异步编程。在这里,我有一个db.query()方法,该方法正在执行一些SQL查询以从数据库中获取数据。在此函数获取数据之后,我们将在.then()函数中进行一些进一步的处理。但是,以这种方式,我面临一些问题。从我调用此getExpensesByFundId(int
fundId)函数的位置来看,它似乎无法正确获取数据。它应该返回Future>对象,然后在数据可用时将其转换为List。但是当我打电话时它不起作用。

但是,我只是对其进行了一些试验,并在db.query()函数之前添加了“
await”关键字,并以某种方式使其开始正常工作。您能否解释为什么添加await关键字可以解决此问题?我以为使用.then()函数时,我们不需要使用await关键字。

这是我的代码:

Future<List<Expense>> getExpensesByFundId(int fundId) async {
    Database db = await database;

    List<Expense> expenseList = List();

   // The await in the below line is what I'm talking about

    await db.query(expTable,where: '$expTable.$expFundId = $fundId')
        .then((List<Map<String,dynamic>> expList){
      expList.forEach((Map<String, dynamic> expMap){
        expenseList.add(Expense.fromMap(expMap));
      });
    });
    return expenseList;
  }

阅读 348

收藏
2020-08-13

共1个答案

一尘不染

简单来说:

await旨在中断流程直到异步方法完成。 then但是不会中断处理流程(意味着将执行下一条指令),但是使您可以在异步方法完成后运行代码。

在您的示例中,您无法实现使用时想要的功能,then因为代码不是“等待中”,并且该return语句已处理,因此返回一个空列表。

当您添加时await,您会明确地说:’直到我Future完成为止(该then部分),再继续。

您可以按照以下方式编写代码,以仅通过以下方式获得相同的结果await

Future<List<Expense>> getExpensesByFundId(int fundId) async {
    Database db = await database;

    List<Expense> expenseList = List();

    List<Map<String,dynamic>> expList = await db.query(expTable,where: '$expTable.$expFundId = $fundId');
    expList.forEach((Map<String, dynamic> expMap) {
        expenseList.add(Expense.fromMap(expMap));
    });

    return expenseList;
}

您也可以选择仅使用该then部分,但是需要确保getExpensesByFundId随后正确调用:

Future<List<Expense>> getExpensesByFundId(int fundId) async {
    Database db = await database;

    List<Expense> expenseList = List();

    return db.query(expTable,where: '$expTable.$expFundId = $fundId')
        .then((List<Map<String,dynamic>> expList){
      expList.forEach((Map<String, dynamic> expMap){
        expenseList.add(Expense.fromMap(expMap));
      });
    });
}

// call either with an await
List<Expense> list = await getExpensesByFundId(1);
// or with a then (knowing that this will not interrupt the process flow and process the next instruction
getExpensesByFundId(1).then((List<Expense> l) { /*...*/ });
2020-08-13