Flutter异步处理增强插件rx_future的使用

发布于 1周前 作者 ionicwang 来自 Flutter

Flutter异步处理增强插件rx_future的使用

RxFuture 是一个强大的库,它将 Getx Rx 集成到一起,引入了一种新的类型 RxFuture,使得处理未来状态(加载、错误)并获取该未来的结果变得更加容易,并且具有一些功能如取消未来。

快速入门

添加依赖

pubspec.yaml 文件中添加以下依赖:

dependencies:
  rx_future: ^1.0.3

使用方法

  1. 导入 rx_future 和 Get 状态管理器,然后创建自己的 GetxController
import 'package:get/state_manager.dart';
import 'package:rx_future/rx_future.dart';

class MyController extends GetxController {}
  1. 声明你的 rxFuture,并传递初始值。
class MyController extends GetxController {
    RxFuture<Map<String, dynamic>> state = RxFuture({});
}
  1. 定义你的函数来触发未来。
class MyController extends GetxController {
  RxFuture<Map<String, dynamic>> state = RxFuture({});

  Future<void> getData() async {

  }
}
  1. 现在通过将一个未来回调传递给 observe 方法来触发状态。
class MyController extends GetxController {
  RxFuture<Map<String, dynamic>> state = RxFuture({});

  Future<void> getData() async {
    await state.observe((value) async {
      return await myApi();
    });
  }
}
  1. 现在你可以在 UI 代码中监听 state.errorstate.loading
Obx(() {
    if(myController.state.loading){
        return const CircularProgressIndicator();
    }

    if(myController.state.hasError){
        return Text(myController.state.error.toString());
    }

    return MyWidget(myController.state.result);
})

更多功能

钩子

有许多钩子会在不同情况下触发,例如:

await state.observe(
  (value) async {
    return await myApi();
  },
  onSuccess: (value) {
     print("success $value");
  },
  onError: (e) {},
  onCancel: () {},
);

例如,现在取消你的未来变得很容易,只需调用 RxFuture.cancel() 方法:

void cancel(){
  state.cancel();
}

多次调用行为

默认情况下,当你多次调用 state.observe() 并且它尚未完成时,它会忽略新调用,直到第一次调用完成。你可以通过传递 MultipleCallsBehavior 参数来更改此行为:

state.observe(
  (val) async {
    return await myApi();
  },
  multipleCallsBehavior: MultipleCallsBehavior.abortNew,
)

要忽略旧调用并刷新你的状态以响应新调用,请使用 MultipleCallsBehavior.abortOld

state.observe(
  (val) async {
    return await myApi();
  },
  multipleCallsBehavior: MultipleCallsBehavior.abortOld,
)

示例 Demo

以下是完整的示例代码:

import 'dart:math';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:rx_future/rx_future.dart';

void main() {
  Get.put<MyController>(MyController());
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatelessWidget {
  MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;
  final MyController controller = Get.find<MyController>();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
              'You have pushed the button this many times:',
            ),
            FloatingActionButton(
              onPressed: () {
                controller.cancel();
              },
            ),
            Obx(() {
              return Text(
                '${controller.state.result}',
                style: Theme.of(context).textTheme.headline4,
              );
            }),
            Obx(() {
              print("the value of loading is ${controller.state.loading}");
              if (controller.state.loading) {
                return const CircularProgressIndicator();
              } else {
                if (controller.state.hasError) {
                  return Text(controller.state.error.toString());
                }
              }
              return Text("${controller.state.lastResult}");
            }),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          controller.getData();
        },
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ),
    );
  }
}

class MyController extends GetxController {
  RxFuture<int> state = RxFuture(0);

  Future<void> getData() async {
    await state.observe(
      (val) async {
        return await getRandomNumber();
      },
      onSuccess: (val) {
        print("Success Getting Number $val");
      },
    );
  }

  void cancel() {
    state.cancel();
  }
}

Future<int> getRandomNumber() async {
  await Future.delayed(const Duration(seconds: 3));
  return Random().nextInt(500);
}

希望这个示例能帮助你更好地理解和使用 rx_future 插件!


更多关于Flutter异步处理增强插件rx_future的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter异步处理增强插件rx_future的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter中使用rx_future插件进行异步处理增强的代码示例。rx_future是一个用于处理Future对象的增强插件,它允许你将Future转换为一个可观察的对象,这样你就可以更好地管理和响应异步操作的状态变化。

首先,确保你已经在pubspec.yaml文件中添加了rx_future依赖:

dependencies:
  flutter:
    sdk: flutter
  rx_future: ^最新版本号  # 请替换为最新版本号

然后,运行flutter pub get来安装依赖。

接下来是一个简单的代码示例,展示如何使用rx_future来处理异步操作:

import 'package:flutter/material.dart';
import 'package:rx_future/rx_future.dart';
import 'dart:async';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('RxFuture Example'),
        ),
        body: Center(
          child: RxFutureExample(),
        ),
      ),
    );
  }
}

class RxFutureExample extends StatefulWidget {
  @override
  _RxFutureExampleState createState() => _RxFutureExampleState();
}

class _RxFutureExampleState extends State<RxFutureExample> {
  final RxFuture<String> _future = RxFuture<String>(() async {
    // 模拟一个耗时操作,例如网络请求
    await Future.delayed(Duration(seconds: 2));
    return 'Data Loaded!';
  });

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        // 显示加载状态
        Obx(() => Text(
          _future.isLoading ? 'Loading...' : '',
          style: TextStyle(fontSize: 20),
        )),

        // 显示加载错误(如果有)
        Obx(() => Text(
          _future.hasError ? _future.error.toString() : '',
          style: TextStyle(color: Colors.red, fontSize: 20),
        )),

        // 显示加载结果
        Obx(() => Text(
          _future.value ?? '',
          style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
        )),

        // 触发异步操作按钮
        SizedBox(height: 20),
        ElevatedButton(
          onPressed: () {
            _future.reload(); // 重新触发异步操作
          },
          child: Text('Reload Data'),
        ),
      ],
    );
  }
}

在这个示例中,我们做了以下几件事:

  1. 创建了一个RxFuture<String>对象,它包装了一个模拟耗时操作的异步函数。
  2. 使用Obx小部件来监听RxFuture对象的状态变化(加载中、错误、结果)。
  3. 根据RxFuture对象的状态,动态显示加载提示、错误信息或加载结果。
  4. 提供了一个按钮,点击后可以重新触发异步操作。

这样,通过使用rx_future,你可以更加灵活地处理异步操作的状态,并在UI中实时反映这些状态的变化。

回到顶部