我有兴趣了解为什么第一个表达式无法更新我的状态,但是第二个表达式可以工作。这段代码使用built_value和bloc。

yield this.state.rebuild(
     (b) async => b..things = await thingRepo.things(),
);

List<Thing> _things = await thingRepo.things();
yield this.state.rebuild(
     (b) async => b..things = _things,
);

最佳答案

Built.rebuild是同步的。如果给出了异步回调,它将不会等待它完成。

  • rebuild从原始Builder值创建一个Built
  • Builder传递给您的回调,希望您的回调对其进行突变。
  • 然后,
  • rebuild返回根据突变的Built创建的新Builder。请注意,回调返回的值将被忽略。

  • 如果您的回调没有同步地更改Builder,那么rebuild将最终返回任何原始值。这是您第一个示例中出问题的地方:您的回调await是在对Future进行变异之前,是Builder。到发生突变时,为时已晚:rebuild已经返回了Built值。

    在第二个示例中,您已将await移到了回调之外。 rebuild立即获取突变值,因此将其用于返回的值。请注意,即使您在第二种情况下的回调被声明为async,该回调也会立即执行突变。

    考虑类似:

      var x = MyBuiltValue((b) => b
        ..foo = 0
        ..bar = 0);
      x = x.rebuild((b) async {
        b.foo = 123;
        await Future.delayed(const Duration(seconds: 0));
        b.bar = 456;
      });
    

    最终,x.foo123,而x.bar仍为0

    10-08 16:34