Pot*_*ato 9 future async-await dart flutter
我正在学习有关使用 Dart 进行异步编程的课程,但出于某种原因,我有点困惑。我想我理解您应该如何使用异步函数的概念,当它可能需要一些时间时,而不是阻塞和冻结您的应用程序,而是使用异步函数,以便执行下一个代码块或方法,以及何时执行异步函数完成或准备好执行。(如果我的理解有缺陷,请告诉我)
但是,我并没有真正了解 Future<> 部分。我知道它可以用作异步函数的返回类型,因为本质上你是说该函数现在返回一个未来的对象,但让我们在它完成后回到它。但是我的导师有点让我困惑,有时她有一个 future 作为返回类型,而另一次她没有把它放在那里,它们都是异步函数。所以现在我很难理解什么时候需要明确声明 Future 返回类型,即使它是无效的?也不只是使用 async 并等待一个函数已经创建了一个未来的对象吗?非常感谢任何澄清,谢谢。
Gar*_* AP 11
是的,使用 async 关键字将使函数自动返回一个 Future。
即使对于 void 函数,显式声明函数的返回类型总是更好,否则编译器会将函数解释为具有动态返回类型。
它还将帮助/使读者更容易了解函数的返回类型。
此外,您需要将对象包装在 Future 中的异步函数中,如下所示:
Future<Object> getObject() async {
final object = await timeConsumingTask();
return object;
}
Run Code Online (Sandbox Code Playgroud)
如果你这样写而不包装它:
Object getObject() async {
final object = await timeConsumingTask();
return object;
}
Run Code Online (Sandbox Code Playgroud)
编译器抛出错误: Functions marked 'async' must have a return type assignable to 'Future'.
对于 void 函数,似乎您不必将返回类型包装在 Future 中,所以这样的事情很好:
void doSomething() async {
await timeConsumingTask();
print('done');
}
Run Code Online (Sandbox Code Playgroud)
让我们考虑一个gatherNewsReports()
只返回 a的方法Future<String>
。Future
from的字符串值gatherNewsReports
。的实施gatherNewsReports
。
// Imagine this is a slow method. Takes time to finish
Future<String> gatherNewsReports() => Future.delayed(Duration(seconds: 1), () => news);
Run Code Online (Sandbox Code Playgroud)
我们将使用Future
和进行方法调用的所有可能组合async
。我要做的方法叫做getDailyNewsDigest
该方法的一个定义可能是与Future
和async
在方法调用给出:
Future<String> getDailyNewsDigest() async {
var str = await gatherNewsReports();
print(str);
return str;
}
Run Code Online (Sandbox Code Playgroud)
请记住gatherNewsReports()
返回 a 的那个Future<String>
。我们只是返回任何gatherNewsReports
回报。
用法:
main() async {
await getDailyNewsDigest();
print('call done');
}
Run Code Online (Sandbox Code Playgroud)
输出:
<gathered news goes here>
call done
Run Code Online (Sandbox Code Playgroud)
评论:这看起来很简单。您只需调用该方法并等待它。请记住,我们await
在getDailyNewsDigest
从main
方法调用时使用了关键字。所以,除非我们通过1 second
,即它需要Future
执行的持续时间。如果我们没有使用 await 关键字,那么输出顺序将被颠倒。
该方法的一种定义可能与方法调用中的Future
given 和async
NOT given 相同:
Future<String> getDailyNewsDigest() {
var str = await gatherNewsReports();
print(str);
return str;
}
Run Code Online (Sandbox Code Playgroud)
这是无效的,因为await
在这种情况下,您不能使用 调用方法gatherNewsReports
。这是无效的。
我们定义的方法可能是Future
NOT GIVEN并async
在方法调用中给出。由于返回类型将是void
我们不会返回任何内容(注意:如果我们尝试返回 aFuture
或 a以外的任何内容,void
则会出现错误):
void getDailyNewsDigest() async {
var str = await gatherNewsReports();
print(str);
}
Run Code Online (Sandbox Code Playgroud)
这是一个有效的方法定义。现在,由于方法被声明为void
我们不能await
在main
方法上。更新的main
方法。
main() async {
getDailyNewsDigest(); // We can't await on it since return is void
print('call done');
}
Run Code Online (Sandbox Code Playgroud)
输出:
call done
<gathered news goes here>
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,因为在getDailyNewsDigest
没有await
反转输出的情况下不会调用该方法。我们不再等待getDailyNewsDigest
完成。
我们定义的方法可能是用Future<Void>
的,而不是Future<String>
和async
在方法调用给出:
Future<void> getDailyNewsDigest() async {
var str = await gatherNewsReports();
print(str);
return;
}
Run Code Online (Sandbox Code Playgroud)
现在在我们的 main 方法中,我们可以await
再次使用关键字来调用getDailyNewsDigest
.
main() async {
await getDailyNewsDigest(); // We can await on it since return is Future<Void> but don't care on the output since it returns nothing
print('call done');
}
Run Code Online (Sandbox Code Playgroud)
这是我能想到的4种组合。
至于这个:
但是我的导师有点让我困惑,有时她有一个 future 作为返回类型,而另一次她没有把它放在那里,它们都是异步函数。
声明一个方法Future
意味着你可以等待它,声明它void
意味着你不能await
在它里面。你当然也可以选择不await
上Future
,如果你不介意做的输出任何东西Future
。如果您以不希望任何人依赖该方法的输出的方式编写代码,即,Future
否则我们将从该方法返回的 d 将自行处理,我们所关心的只是触发它- 并-继续我们的工作;在这种情况下,我们应该使用返回类型定义我们的方法void
。