在 Dart/Flutter 中异步/等待/然后 [英] Async/Await/then in 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屋!