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 【问题描述】:

有什么区别:

未来,异步,等待,然后,catchError

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'));

所有方法都有效。如果我使用thencatchError,我还需要将代码包装在async 函数中吗?

推荐的方式是什么?

【问题讨论】:

只有在函数体中使用 await 时才使用 async - 在这种情况下,async 函数不应返回 void,因为无法检查函数何时完成- 你应该返回一个Future(即使它是Future&lt;void&gt; 当使用 async / await 东西时,有一点需要使用 Future` API - then()catchError() - 更多阅读 dart.dev/codelabs/async-await 和 dart.dev/guides/libraries/futures-error-handling跨度> 【参考方案1】:

首先async/awaitthen的概念基本相同。很多人说async/await是处理Promise的更优雅的方式(因为它看起来更有条理)。这两个想法的作用是:“做某事,一旦完成,就做其他事情”。

关于Future&lt;void&gt; 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&lt;void&gt; 而不是 void 不,因为你没有返回任何东西。当你有一个未来作为返回类型时,你还需要返回一个未来,如第二块所示。

以上是关于Flutter/Dart 中的 Future<void>, async, await, then, catchError的主要内容,如果未能解决你的问题,请参考以下文章

Flutter/Dart - 调用一个 Future<String> ...但只需要返回一个 String 的函数

如何在Flutter / Dart中创建异步回调?

如何使用 HTTP 请求(Flutter/Dart)检查 Internet 连接?

Flutter——dart 异步

使用 Flutter/Dart 的 URL 启动器

在 Flutter/Dart 中的列表内创建地图