Flutter并发网络请求插件fetch_pool的使用

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

Flutter并发网络请求插件fetch_pool的使用

FetchPool 是一个库,可以轻松并异步地下载一组URL列表,同时使用给定的最大并发连接数。这使您可以下载数百个文件,而同时只下载其中几个。

使用

以下是一个简单的使用示例:

import 'package:fetch_pool/fetch_pool.dart';

void main() async {
  const urls = [
    "https://picsum.photos/id/0/5616/3744",
    "https://picsum.photos/id/1/5616/3744",
    "https://some.invalid.url/to/simulate/an/error", // 故意设置错误
    "https://picsum.photos/id/1001/5616/3744",
    "https://picsum.photos/id/1002/4312/2868",
    "https://picsum.photos/id/1003/1181/1772",
    "https://picsum.photos/id/1004/5616/3744",
    "https://picsum.photos/id/1005/5760/3840",
  ];

  final pool = FetchPool(
      maxConcurrent: 2,
      urls: urls,
      destinationDirectory: "./deep/path/to/images");

  final results = await pool.fetch(progressCallback: (progress) {
    print('Total progress: $progress');
  });

  results.forEach((url, result) {
    if (result.isSuccess) {
      print('SUCCESS: $url > ${result.localPath}');
    } else {
      print('FAILURE: $url > ${result.error}');
    }
  });
}

上述代码将尝试将URL列表下载到给定的 destinationDirectory 中。它将最多同时使用两个连接,并通过给定的 progressCallback 报告总进度。

默认情况下,下载的文件将使用 FetchPoolFileNamingStrategy.basename 策略命名。这意味着像 https://test.com/img.png?a=123&b=456 这样的URL将会生成本地文件名为 img.png。如果使用 basenameWithQueryParams,则会生成 img_a_123_b_456.png。如果使用 base64EncodedUrl,则会使用整个URL进行base64编码,生成的本地文件名为 aHR0cHM6Ly90ZXN0LmNvbS9pbWcucG5nP2E9MTIzJmI9NDU2

默认情况下,将使用 FetchPoolFileOverwritingStrategy.overwrite 策略。这意味着在 destinationDirectory 中任何同名的现有文件都将被覆盖。如果使用 FetchPoolFileOverwritingStrategy.skip 策略,则会跳过已存在的文件,不会尝试下载它们。每个请求的URL对应的 FetchPoolResult 对象都有一个 persistenceResult 属性,指示文件是否被持久化(保存、覆盖或跳过)。

完整示例

以下是完整的示例代码,展示了如何使用 fetch_pool 插件并发下载多个图片:

import 'package:fetch_pool/fetch_pool.dart';

void main() async {
  const urls = [
    'https://picsum.photos/id/0/5616/3744',
    'https://picsum.photos/id/1/5616/3744',
    'https://picsum.photos/id/10/2500/1667',
    'https://picsum.photos/id/100/2500/1656',
    'https://picsumwursttest.photos/id/1000xAAA/5626/3635', // 故意设置错误
    'https://picsum.photos/id/1001/5616/3744',
    'https://picsum.photos/id/1002/4312/2868',
    'https://picsum.photos/id/1003/1181/1772',
    'https://picsum.photos/id/1004/5616/3744',
    'https://picsum.photos/id/1005/5760/3840',
    'https://picsum.photos/id/1006/3000/2000',
    'https://picsum.photos/id/1008/5616/3744',
    'https://picsum.photos/id/1009/5000/7502',
    'https://picsum.photos/id/101/2621/1747',
    'https://picsum.photos/id/1010/5184/3456',
    'https://picsum.photos/id/1011/5472/3648',
    'https://picsum.photos/id/1012/3973/2639',
    'https://picsum.photos/id/1013/4256/2832',
    'https://picsum.photos/id/1014/6016/4000',
    'https://picsum.photos/id/1015/6000/4000',
    'https://picsum.photos/id/1016/3844/2563',
    'https://picsum.photos/id/1018/3914/2935',
    'https://picsum.photos/id/1019/5472/3648',
    'https://picsum.photos/id/102/4320/3240',
    'https://picsum.photos/id/1020/4288/2848',
    'https://picsum.photos/id/1021/2048/1206',
    'https://picsum.photos/id/1022/6000/3376',
    'https://picsum.photos/id/1023/3955/2094',
    'https://picsum.photos/id/1024/1920/1280',
    'https://picsum.photos/id/1025/4951/3301'
  ];

  final pool = FetchPool(
      maxConcurrent: 2,
      urls: urls,
      destinationDirectory: './deep/path/to/images');

  final results = await pool.fetch(progressCallback: (progress) {
    print('Total progress: $progress');
  });

  results.forEach((url, result) {
    if (result.isSuccess) {
      print('SUCCESS: $url > ${result.localPath}');
    } else {
      print('FAILURE: $url > ${result.error}');
    }
  });

  print('Done');
}

更多关于Flutter并发网络请求插件fetch_pool的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter并发网络请求插件fetch_pool的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,关于如何在Flutter中使用fetch_pool插件进行并发网络请求,下面是一个详细的代码示例。fetch_pool是一个帮助管理并发网络请求的Flutter插件,可以显著提高网络请求的效率和性能。

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

dependencies:
  flutter:
    sdk: flutter
  fetch_pool: ^最新版本号  # 请替换为实际的最新版本号

然后,运行flutter pub get来获取依赖。

接下来,在你的Flutter项目中,你可以按照以下步骤使用fetch_pool进行并发网络请求:

  1. 导入fetch_pool
import 'package:fetch_pool/fetch_pool.dart';
  1. 配置和初始化FetchPool
void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  // 初始化 FetchPool,设置最大并发数等参数
  final fetchPool = FetchPool(
    maxConcurrent: 5, // 最大并发请求数
    timeout: Duration(seconds: 10), // 每个请求的超时时间
  );

  runApp(MyApp(fetchPool: fetchPool));
}
  1. 创建网络请求任务
Future<Map<String, dynamic>> fetchData(String url) async {
  final response = await http.get(Uri.parse(url));
  if (response.statusCode == 200) {
    return jsonDecode(response.body);
  } else {
    throw Exception('Failed to load data: ${response.statusCode}');
  }
}
  1. 使用FetchPool执行并发请求
class MyApp extends StatefulWidget {
  final FetchPool fetchPool;

  MyApp({required this.fetchPool});

  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  void initState() {
    super.initState();

    final urls = [
      'https://api.example.com/data1',
      'https://api.example.com/data2',
      'https://api.example.com/data3',
      // 添加更多URL
    ];

    // 使用 FetchPool 执行并发请求
    widget.fetchPool.fetchAll(urls.map((url) => fetchData(url)).toList()).then((results) {
      // 所有请求完成后处理结果
      print('All requests completed with results: $results');
      // 你可以在这里更新UI
      setState(() {
        // 例如,将结果存储在状态中
      });
    }).catchError((error) {
      // 处理错误
      print('Error occurred: $error');
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Fetch Pool Example'),
        ),
        body: Center(
          child: Text('Loading data...'), // 在这里显示加载状态
        ),
      ),
    );
  }
}

在这个示例中,我们首先初始化了FetchPool实例,并设置了最大并发数和超时时间。然后,我们定义了一个fetchData函数来执行网络请求。在MyApp组件的initState方法中,我们使用fetchPool.fetchAll方法来并发执行多个网络请求,并在所有请求完成后处理结果。

请注意,这只是一个简单的示例,实际应用中你可能需要更复杂的错误处理和UI更新逻辑。此外,确保在实际项目中处理网络请求时考虑到数据的安全性和隐私保护。

回到顶部