如何在 Dart/Flutter 中克隆 Future

问题描述 投票:0回答:1

我有一个自定义的 FLutter 小部件,它接收 future 作为其构造函数的参数,并且内部有

FutureBuilder

我想添加在连接错误的情况下重新运行此 future 的功能,但问题是首次使用后 future 已“耗尽”。因此,我需要某种方法来创建作为参数传递的未来的副本,以便每次用户按下“重新加载”按钮时使用

FutureBuilder
内部的副本。

import 'package:flutter/material.dart';

class CustomFutureBuilder<T> extends StatefulWidget {
  final Future<T> future;

  const CustomFutureBuilder({super.key, required this.future});

  @override
  State<CustomFutureBuilder<T>> createState() => _CustomFutureBuilderState<T>();
}

class _CustomFutureBuilderState<T> extends State<CustomFutureBuilder<T>> {
  late Future<T> _future;

  @override
  void initState() {
    // I need to use initState to initialize _future for the first usage of this widget
    _future = widget.future; // ← here I want to create a future clone and use it instead of original
    super.initState();
  }

  @override
  void didUpdateWidget(covariant CommonFutureBuilder<T> oldWidget) {
    _future = widget.future; // ← and here too
    super.didUpdateWidget(oldWidget);
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: _future,
      builder: (context, snapshot) {
        if (snapshot.connectionState != ConnectionState.done) {
          return const LinearProgressIndicator();
        }
        if (snapshot.hasError) {
          debugPrint('Loading error: ${snapshot.error}');
          return Column(
            children: [
              const Text(
                  'Loading error is occurred. Check the internet connection or try again later.'),
              OutlinedButton(
                onPressed: () {
                  setState(() {
                    // ← and maybe here too, I am not sure
                  });
                },
                child: const Text('Reload'),
              ),
            ],
          );
        }

        final data = snapshot.data as T;
        return …
      },
    );
  }
}

flutter dart future flutter-futurebuilder
1个回答
0
投票

你可以尝试用

StreamBuilder
替换
FutureBuilder
,因为
Future
无法监听变量变化。这是一次性响应。相反,您需要使用
Stream
进行用户刷新或事件。

这是您案例的代码:

      late StreamController<T> _conStream;
      @override
      void initState() {
        _conStream= StreamController<T>(); 
        super.initState();
      }
  @override
  void dispose() async {
    _conStream.onCancel;
   await  _conStream.close();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return StreamBuilder(
          stream: _conStream.stream,
...
  • 刷新功能:

     _conStream.add(await Future.delayed(Duration(seconds: 5), () => 'Done') // as example);
    
© www.soinside.com 2019 - 2024. All rights reserved.