未来成功完成,但数据功能从未执行

问题描述

这段代码有问题,但我不知道是什么。

问题是 loading 被执行,Future 成功完成并打印 “From the onPress”,但是 data 函数从未执行所以永远不会打印 “通过按钮完成!!!”

这是一个重现问题的示例:

import 'package:Flutter/material.dart';
import 'package:Flutter_riverpod/Flutter_riverpod.dart';

void main() {
  runApp(ProviderScope(child: MaterialApp(home: Scaffold(body: Center(child: MyHomeAsyncValue()),))));
}

final voidFutureProvider = FutureProvider.autodispose.family<void,String>((ref,str) {
  return Future.delayed(Duration(seconds: 5),() { print(str); });
});

class MyHomeAsyncValue extends ConsumerWidget {
  MyHomeAsyncValue({Key? key,}) : super(key: key);

  @override
  Widget build(BuildContext context,ScopedReader watch) {
    return ElevatedButton(
      child: Text('Call'),onpressed: () {
        final AsyncValue<void> fromButton = context.read(voidFutureProvider("From the onPress"));
        fromButton.when(
            data: (value) => print("Done from the button!!!"),loading: () => print("Loading...."),error: (error,stackTrace) => print("Error $error"),);
      },);
  }
}

注意:我尝试将按钮包裹在 Consumer 中并使用 watch 而不是 read,但结果是一样的。

版本 Flutter_riverpod: ^0.14.0+3

更新: 还测试了避免 void 作为返回类型,结果相同:

final userUpdateFutureProvider = FutureProvider.autodispose.family<User,User>((ref,user) async {
  return Future.delayed(Duration(seconds: 100),() => user);
});

更新:创建了一张票 https://github.com/rrousselGit/river_pod/issues/628

解决方法

创建一个 ticket 后认为它是一个错误,作者反应非常快。

基本上,他的回答是:

这不是 AsyncValue 的工作方式。什么时候不“听” 数据/加载/错误。这是当前状态的开关案例。

因此用下一个新代码替换 onPressed 代码有效:

        onPressed: () {
          final value = context.read(voidFutureProvider("From the onPress").future);
          value
              .then((value) =>  print("Done from the button!!!"))
              .onError((error,stackTrace) => print("Error $error"));
        },

因此该解决方案希望使用内部未来来注册回调。

我不清楚的是为什么相同的代码可以在 onPressed 之外工作? ?

这是一个完整的工作示例:https://github.com/angelcervera/testing_riverpod/blob/main/lib/main_onpress_working.dart