我有兴趣了解为什么第一个表达式无法更新我的状态,但是第二个表达式可以工作。这段代码使用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.foo
为123
,而x.bar
仍为0
。