【问题标题】:Dart relationship between await and completer等待和完成者之间的飞镖关系
【发布时间】:2020-05-16 19:13:31
【问题描述】:

以下示例有些做作,但我正在尝试了解 Completer 与 await 生成的 future 之间的关系。

在下面的示例中,“doCalc”方法包含一个“await”调用和一个 Completer。

据我了解,当 dart 遇到“await”语句时,它会立即停止执行该方法并返回一个未来。

如果您在 dartpad 中运行代码,您可以在输出中看到这一点。立即打印value = Instance of '_Future<int>' 行。

这符合我的预期(即 await 导致方法立即返回)。 您可以从 'value=' 行看到 doCalc 返回了 Future<int>

这也符合预期。

我遇到的问题是 doCalc 的最后一行也返回了一个未来。在这种情况下,未来由完成者生成。

因此,doCalc 似乎返回两个不同的期货。

1) 第一个 dart 在调用 await 时隐式返回。

2) 我通过 return 语句显式返回第二个。

鉴于 'res' 的值必须包含第一个未来(因为我们在完成者的未来返回之前打印它的值),所以 res.then 行如何等待第二个未来完成。

这里似乎有一些魔法,但我找不到任何关于它的文档。

飞镖板链接:

https://dartpad.dev/a42cce3edf01b222206a627e8c8106af

import 'dart:async';
void main() {

  print('hi');
  var res = doCalc();
  print('value = ${res}');

  res.then((result) => print('result = $result'));
}

Future<int> doCalc() async
{
  var done = Completer<int>();

  await Future.delayed(Duration(seconds: 4), 
                 () { 
                   done.complete(10);

                     });

  return done.future;
}

【问题讨论】:

    标签: dart future


    【解决方案1】:

    async 函数返回它自己创建的未来。它“立即”执行此操作,这意味着它会执行主体,直到第一个异步延迟(awaitawait for)在未来返回之前。

    async 函数中的任何 return 语句都用于完成返回的未来。 如果您的async 函数返回Future&lt;int&gt;,那么您的return 语句必须返回intFuture&lt;int&gt;。 在前一种情况下,返回的未来以该整数完成。 在后一种情况下,返回的 future 将完成与 return-future 相同的结果(我们将其命名为) return-future 完成。

    就好像async 函数中的return expression; 实际上是return await expression;。 在本例中,行:

    return done.future;
    

    可以读作

    return await done.future;
    

    这应该可以解释你看到的行为。

    【讨论】:

    • 异步函数内的任何 return 语句都用于完成返回的未来。你的这部分答案不可能是正确的。
    • 取决于您认为“返回的未来”的“未来”。如果你调用一个异步函数foo,那么它会返回一个future。在foo 中执行return 语句时,该return 语句的表达式的值用于完成返回的future。如果 return 语句表达式的值本身是一个未来,那么它可能会在其值用于完成返回的未来之前被等待。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-28
    • 1970-01-01
    • 2019-05-07
    • 2021-09-15
    • 2021-03-11
    相关资源
    最近更新 更多