Flutter处理多个异步请求

Dart 提供了多种方式来实现,包括以下几种

1、使用 Future.wait():Future.wait() 函数可以接收多个 Future 对象,并返回一个 Future 对象,该对象在所有 Future 对象都完成后才会完成。这样,我们可以使用该函数来等待多个异步操作完成后再进行下一步操作。

Future<void> fetchData() async {
  try {
    var response1 = http.get(Uri.parse('https://example.com/data1'));
    var response2 = http.get(Uri.parse('https://example.com/data2'));
    var results = await Future.wait([response1, response2]);
    var data1 = jsonDecode(results[0].body);
    var data2 = jsonDecode(results[1].body);
    print(data1);
    print(data2);
  } catch (e) {
    print('Error: $e');
  }
}

使用 Completer,它可以用于等待多个 Future 对象的完成,并在所有 Future 对象都完成后返回结果。使用 Completer,我们可以将多个异步请求的 Future 对象添加到 Completer 中,并通过监听 Completer 的 future 属性来等待所有 Future 对象的完成。

Future<void> fetchData() async {
  try {
    var completer = Completer<List<dynamic>>();
    var response1 = http.get(Uri.parse('https://example.com/data1'));
    var response2 = http.get(Uri.parse('https://example.com/data2'));
    Future.wait([response1, response2]).then((results) {
      var data1 = jsonDecode(results[0].body);
      var data2 = jsonDecode(results[1].body);
      completer.complete([data1, data2]);
    });
    var results = await completer.future;
    print(results[0]);
    print(results[1]);
  } catch (e) {
    print('Error: $e');
  }
}

2、使用 Stream 和 StreamController:Stream 和 StreamController 是 Dart 中用于处理流的类,它们可以用于实现多个异步请求的并发处理和结果组合。我们可以创建多个 StreamController,并将它们的流合并到一个单独的流中,然后使用 Stream 的各种操作符来处理结果。

Future<void> fetchData() async {
  try {
    var controller1 = StreamController();
    var controller2 = StreamController();
    http.get(Uri.parse('https://example.com/data1'))
        .then((response) => controller1.add(response.body));
    http.get(Uri.parse('https://example.com/data2'))
        .then((response) => controller2.add(response.body));
    var results = await StreamZip([controller1.stream, controller2.stream]).toList();
    var data1 = jsonDecode(results[0]);
    var data2 = jsonDecode(results[1]);
    print(data1);
    print(data2);
  } catch (e) {
    print('Error: $e');
  }
}

3、使用 async* 和 yield:async* 和 yield 是 Dart 中用于创建异步生成器的语法,它们可以用于实现多个异步请求的串行处理和结果组合。我们可以使用 yield 关键字将每个异步请求的结果返回给调用方,从而实现异步请求的串行处理。

Stream<String> fetchData() async* {
  try {
    var response1 = await http.get(Uri.parse('https://example.com/data1'));
    var data1 = jsonDecode(response1.body);
    yield data1.toString();
    var response2 = await http.get(Uri.parse('https://example.com/data2'));
    var data2 = jsonDecode(response2.body);
    yield data2.toString();
  } catch (e) {
    print('Error: $e');
  }
}

4、使用 Isolate:Isolate 是 Dart 中的一种轻量级进程,它可以与其他 Isolate 并行执行,并且与其他 Isolate 共享内存空间。通过使用 Isolate,我们可以在多个独立的 Isolate 中同时执行多个异步请求,并将结果传回主 Isolate 进行处理。

import 'dart:isolate';

void fetchData(SendPort sendPort) async {
  try {
    var response1 = await http.get(Uri.parse('https://example.com/data1'));
    var data1 = jsonDecode(response1.body);
    var response2 = await http.get(Uri.parse('https://example.com/data2'));
    var data2 = jsonDecode(response2.body);
    sendPort.send([data1, data2]);
  } catch (e) {
    sendPort.sendError('Error: $e');
  }
}

Future<void> main() async {
  try {
    var receivePort = ReceivePort();
    await Isolate.spawn(fetchData, receivePort.sendPort);
    var results = await receivePort.first;
    print(results[0]);
    print(results[1]);
  } catch (e) {
    print('Error: $e');
  }
}

使用第三方插件

1、dio:dio 是一个强大的 Dart HTTP 客户端,它支持多个并发请求,并提供了丰富的功能,如拦截器、请求和响应转换等。 这个是最常用的

Future<void> fetchData() async {
  try {
    var dio = Dio();
    var response1 = await dio.get('https://example.com/data1');
    var data1 = response1.data;
    var response2 = await dio.get('https://example.com/data2');
    var data2 = response2.data;
    print(data1);
    print(data2);
  } catch (e) {
    print('Error: $e');
  }
}

2、http_multi_client:http_multi_client 是一个支持并发请求的 Dart HTTP 客户端,它可以在同一个域名下创建多个连接来提高请求效率。

Future<void> fetchData() async {
  try {
    var client = MultiClient();
    var response1 = await client.get(Uri.parse('https://example.com/data1'));
    var data1 = jsonDecode(response1.body);
    var response2 = await client.get(Uri.parse('https://example.com/data2'));
    var data2 = jsonDecode(response2.body);
    print(data1);
    print(data2);
    client.close();
  } catch (e) {
    print('Error: $e');
  }
}

3、flutter_bloc:flutter_bloc 是一个 Flutter 状态管理库,它提供了一种基于 BLoC 模式的方式来处理异步请求。使用 flutter_bloc,我们可以将多个异步请求的结果保存到一个或多个状态对象中,并在 UI 层中根据状态来更新界面。

class DataBloc extends Bloc<DataEvent, DataState> {
  @override
  DataState get initialState => DataLoading();

  @override
  Stream<DataState> mapEventToState(DataEvent event) async* {
    if (event is FetchData) {
      try {
        var response1 = await http.get(Uri.parse('https://example.com/data1'));
        var data1 = jsonDecode(response1.body);
        var response2 = await http.get(Uri.parse('https://example.com/data2'));
        var data2 = jsonDecode(response2.body);
        yield DataLoaded([data1, data2]);
      } catch (e) {
        yield DataLoadFailure('Error: $e');
      }
    }
  }
}

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return BlocBuilder<DataBloc, DataState>(
      builder: (context, state) {
        if (state is DataLoading) {
          return CircularProgressIndicator();
        } else if (state is DataLoaded) {
          return Column(
            children: [
              Text(state.data[0]),
              Text(state.data[1]),
            ],
          );
        } else if (state is DataLoadFailure) {
          return Text(state.error);
        } else {
          return Text('Unknown state');
        }
      },
    );
  }
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容