Flutter/Dart 中的 Future<void>, async, await, then, catchError
Posted
技术标签:
【中文标题】Flutter/Dart 中的 Future<void>, async, await, then, catchError【英文标题】:Future<void>, async, await, then, catchError in Flutter/Dart 【发布时间】:2020-06-19 21:07:45 【问题描述】:有什么区别:
未来
Future<void> copyToClipboard(BuildContext context, String text) async
await Clipboard.setData(ClipboardData(text: text))
.then((_) => showSnackBar(context, 'Copied to clipboard'))
.catchError((Object error) => showSnackBar(context, 'Error $error'));
void、async、await、then、catchError
void copyToClipboard(BuildContext context, String text) async
await Clipboard.setData(ClipboardData(text: text))
.then((_) => showSnackBar(context, 'Copied to clipboard'))
.catchError((Object error) => showSnackBar(context, 'Error $error'));
void,然后,catchError
void copyToClipboard(BuildContext context, String text)
Clipboard.setData(ClipboardData(text: text))
.then((_) => showSnackBar(context, 'Copied to clipboard'))
.catchError((Object error) => showSnackBar(context, 'Error $error'));
所有方法都有效。如果我使用then
和catchError
,我还需要将代码包装在async
函数中吗?
推荐的方式是什么?
【问题讨论】:
只有在函数体中使用await
时才使用 async
- 在这种情况下,async
函数不应返回 void
,因为无法检查函数何时完成- 你应该返回一个Future
(即使它是Future<void>
)
当使用 async
/ await
东西时,有一点需要使用 Future` API - then()
和 catchError()
- 更多阅读 dart.dev/codelabs/async-await 和 dart.dev/guides/libraries/futures-error-handling跨度>
【参考方案1】:
首先async/await
和then
的概念基本相同。很多人说async/await
是处理Promise的更优雅的方式(因为它看起来更有条理)。这两个想法的作用是:“做某事,一旦完成,就做其他事情”。
关于Future<void> copyToClipboard(BuildContext context, String text) async ...
:
在这里,您正在从您的函数返回一个 Promise。意思是,您可以使用
await copyToClipboard(context,"Text");
print("Done");
但是,您也可以返回 Promise 本身(然后在调用该函数的任何位置处理它):
Future<void> copyToClipboard(BuildContext context, String text) async
return Clipboard.setData(ClipboardData(text: text));
void somewhereElse() async
await copyToClipboard(context,"Text"); // (1)
print("Copied"); //Happens after (1)
因此,如果您使用then
,您将把以下指令放入它调用的相应函数中(如您的第 3 个 sn-p 所示)。用 async 解决第二个 sn-p 看起来像这样:
void copyToClipboard(BuildContext context, String text) async
await Clipboard.setData(ClipboardData(text: text));// (1)
showSnackBar(context, 'Copied to clipboard')); // (2) This will only be called when (1) has completed
如果这条指令抛出错误,你可以将它包装到一个 try/catch 块中:
void copyToClipboard(BuildContext context, String text) async
try
await Clipboard.setData(ClipboardData(text: text));// (1)
showSnackBar(context, 'Copied to clipboard')); // (2) This will only be called when (1) has completed
catch (error)
print(error.message);
如果您更喜欢 then/wait 或 async/await 取决于您。我会推荐异步/等待。请记住,在使用 async/await 时,您需要将 async
关键字放入函数的签名中,以便调用该函数的函数知道,调用它可能需要一段时间并等待它。
【讨论】:
感谢您的回答。在您最新的代码示例中,异步函数是否应该返回Future<void>
而不是 void
?
不,因为你没有返回任何东西。当你有一个未来作为返回类型时,你还需要返回一个未来,如第二块所示。以上是关于Flutter/Dart 中的 Future<void>, async, await, then, catchError的主要内容,如果未能解决你的问题,请参考以下文章
Flutter/Dart - 调用一个 Future<String> ...但只需要返回一个 String 的函数