【问题标题】:Asynchronous in dart飞镖中的异步
【发布时间】:2021-11-28 15:21:28
【问题描述】:

在 Dart DOC 网站上,我看到了这个异步示例,

    Future<void> printOrderMessage() async {
  print('Awaiting user order...');
  var order = await fetchUserOrder();
  print('Your order is: $order');
}

Future<String> fetchUserOrder() {
  return Future.delayed(const Duration(seconds: 4), () => 'Large Latte');
}

Future<void> main() async {
  countSeconds(4);
  await printOrderMessage();
}

void countSeconds(int s) {
  for (var i = 1; i <= s; i++) {
    Future.delayed(Duration(seconds: i), () => print(i));
  }
}


// output


Awaiting user order...
1                       // after 1 second
2                       // after 2 second
3                       //after 3 second
4                       // after 4 second
Your order is: Large Latte  // after 4 second

在我通过将 printOrderMessage() 和 main() 的返回类型转换为 void 来更改代码之后 并去掉 main() 的 async 和 await ,输出相同的结果

 printOrderMessage() async {
  print('Awaiting user order...');
  var order = await fetchUserOrder();
  print('Your order is: $order');
}

Future<String> fetchUserOrder() {
  return Future.delayed(const Duration(seconds: 4), () => 'Large Latte');
}

  main() {
  countSeconds(4);
  printOrderMessage();
}

void countSeconds(int s) {
  for (var i = 1; i <= s; i++) {
    Future.delayed(Duration(seconds: i), () => print(i));
  }
}

// 输出

Awaiting user order...
1                       // after 1 second
2                       // after 2 second
3                       //after 3 second
4                       // after 4 second
Your order is: Large Latte  // after 4 second

如果显示相同的结果,为什么我们需要在 main() 中同步和等待并返回 Future 类型?

【问题讨论】:

    标签: dart asynchronous future


    【解决方案1】:

    void 关键字对于返回 null 的函数是可选的。 Future&lt;void&gt; 也是如此。 它们可以在不更改任何内容的情况下删除。

    await 关键字将暂停异步函数的执行,直到等待的函数返回。在您的示例中,printOrderMessage() 位于main() 的最后一行。是否等待都没关系,因为在 printOrderMessage() 返回后没有其他代码可以执行。

    如果printOrderMessage 在countSeconds 之前,await 关键字将改变输出:

    main() async {
      printOrderMessage();
      countSeconds(4);
    }
    
    
    main() async {
      await printOrderMessage();
      countSeconds(4);
    }
    

    【讨论】:

      【解决方案2】:

      您的main 中不需要async 和await。 正如所写,它没有任何区别。

      不忽略异步行为是好习惯,这里使用async 和await 突出显示异步实际上正在发生。

      这个程序的行为无关紧要,因为最后的await printOrderMessage();所做的只是从printOrderMessage()接收一个future,等待它完成,然后完成@987654328 @ 由main 返回(由于async 而返回)带有null 或相同的错误,如果等待的未来以错误完成。没有人等待main 返回的未来,因此任何值结果都将被忽略,任何错误都将成为未捕获的异步错误。如果你只写printOrderMessage(); 而不写await 会发生同样的情况——该值被忽略并且错误未被捕获。

      如果有人可以访问 main 返回的未来,那么您会看到不同之处 - main 未来将在没有 await 的情况下立即完成,而不是等待,并且不会出现相同的错误(它不能,因为它没有等待它)。这使得main 变得特别,作为没有人看到结果的一个函数,最好养成等待所有未来的习惯,而不是担心你是否真的需要在main 方法中这样做.

      如果await 不是main 函数的最后一个操作,那也很重要,因为await 会延迟之后的所有操作。在这里,await之后什么都没有。

      【讨论】:

      • 由于await 将暂停main() 的执行,如果在等待的函数之后有一些代码要执行,那将会有所不同。这不仅仅是访问 main() 返回的未来。请参阅我答案的最后一部分。除非我错了,否则你的回答很具有误导性。
      • 本程序中await后面没有代码。如果有,那么是的,省略等待会改变时间。这里的问题是 await 是函数的 last 操作,并且没有人监听函数返回的未来。最初的问题是为什么删除async 和await 没有区别。我添加了一条评论,说 await 最后也很重要。
      猜你喜欢
      • 2021-09-05
      • 2020-11-28
      • 2019-05-07
      • 1970-01-01
      • 2019-02-12
      • 2018-08-14
      • 1970-01-01
      • 2018-12-29
      • 1970-01-01
      相关资源
      最近更新 更多