首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Async/Await/then in Dart/Flutter

Async/Await/then in Dart/Flutter
EN

Stack Overflow用户
提问于 2019-02-04 19:28:47
回答 3查看 40K关注 0票数 22

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

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

以下是我的代码:

代码语言:javascript
复制
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;
  }
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-02-04 19:55:44

简而言之:

await旨在中断进程流,直到async方法完成。但是,then不会中断进程流(意味着将执行下一条指令),但允许您在async方法完成时运行代码。

在您的示例中,当您使用then时,您无法实现您想要的结果,因为代码不是‘等待’,并且return语句被处理,从而返回一个空列表。

当您添加await时,您会显式地说:‘在我的Future方法(即then部分)完成之前,不要执行下一步操作。

您可以按如下方式编写代码,以仅使用await实现相同的结果

代码语言:javascript
复制
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

代码语言:javascript
复制
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) { /*...*/ });
票数 58
EN

Stack Overflow用户

发布于 2020-08-25 21:09:53

补充上面的答案。

Flutter应用程序据说是一步一步地执行代码,但事实并非如此。在应用程序的生命周期中会触发很多事件,比如Click事件、计时器等等。必须有一些代码应该在后台线程中运行。

后台工作如何执行:

因此有两个Queues

  1. 微任务队列
  2. Event Queue

Microtask Queue运行的代码不应该由任何事件(点击、计时器等)运行。它可以同时包含同步和异步工作。

当应用程序中发生任何外部单击事件时,Event Queue都会运行,然后在事件循环内完成该块的执行。

下图将详细解释如何继续执行。

注意:在应用程序开发的任何给定时间点,都将运行微任务队列,然后只能运行事件队列。

票数 2
EN

Stack Overflow用户

发布于 2020-04-17 00:24:48

在创建类时,使用async来使用await,它简单逻辑是在函数中设置一个等待状态,直到检索到要显示的数据为止。

示例: 1)这就像你点击按钮2)数据首先存储在数据库中,而不是Future函数用来检索数据3)将数据移动到变量中,然后在屏幕上显示4)变量在下面/配置文件中显示类似增量。

then是一步一步地使用代码,将数据存储在变量中,然后移动到下一步。

例如:如果我点击follow按钮,直到数据存储在变量中,它会连续检索一些要存储的数据,并且不允许运行下一个函数,如果一个任务完成,则移动到另一个任务。

和你的问题一样,我也在做社交媒体flutter应用的实验,这是我的理解。我希望这能有所帮助。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54515186

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档