在 Dart/Flutter 中异步/等待/然后 [英] Async/Await/then in Dart/Flutter

查看:39
本文介绍了在 Dart/Flutter 中异步/等待/然后的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a flutter application where I am using the SQFLITE plugin to fetch data from SQLite DB. Here I am facing a weird problem. As per my understanding, we use either async/await or then() function for async programming. Here I have a db.query() method which is conducting some SQL queries to fetch data from the DB. After this function fetches the data, we do some further processing in the .then() function. However, in this approach, I was facing some issues. From where I am calling this getExpensesByFundId(int fundId)function, it doesn't seem to fetch the data properly. It's supposed to return Future> object which will be then converted to List when the data is available. But when I call it doesn't work.

但是,我只是对它进行了一些实验,并在 db.query() 函数前添加了await"关键字,不知何故,它开始正常工作.你能解释为什么添加 await 关键字可以解决这个问题吗?我想在使用 .then() 函数时,我们不需要使用 await 关键字.

However, I just did some experimentation with it and added "await" keyword in front of the db.query() function and somehow it just started to work fine. Can you explain why adding the await keyword is solving this issue? I thought when using .then() function, we don't need to use the await keyword.

这是我的代码:

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;
  }

推荐答案

简单来说:

await 用于中断流程,直到 async 方法完成.then 但是不会中断流程(意味着将执行下一条指令),而是使您能够在 async 方法完成时运行代码.

await is meant to interrupt the process flow until the async method has finished. then however does not interrupt the process flow (meaning the next instructions will be executed) but enables you to run code when the async method is finished.

在你的例子中,当你使用 then 时你不能实现你想要的,因为代码不是等待"并且 return 语句被处理并因此返回一个空清单.

In your example, you cannot achieve what you want when you use then because the code is not 'waiting' and the return statement is processed and thus returns an empty list.

当您添加 await 时,您明确地说:在我的 Future 方法完成(即 then部分).

When you add the await, you explicitly say: 'don't go further until my Future method is completed (namely the then part).

您可以编写如下代码以仅使用 await 来实现相同的结果:

You could write your code as follows to achieve the same result using only 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:

You could also choose to use only the then part, but you need to ensure that you call getExpensesByFundId properly afterwards:

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) { /*...*/ });

这篇关于在 Dart/Flutter 中异步/等待/然后的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆