# AsyncTaskTrigger **Repository Path**: kaelinda/async-task-trigger ## Basic Information - **Project Name**: AsyncTaskTrigger - **Description**: 基于信号量实现的异步任务触发器 - **Primary Language**: Objective-C - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 2 - **Forks**: 0 - **Created**: 2020-09-17 - **Last Updated**: 2022-04-24 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # AsyncTaskTrigger [![CI Status](https://img.shields.io/travis/zuosong/AsyncTaskTrigger.svg?style=flat)](https://travis-ci.org/zuosong/AsyncTaskTrigger) [![Version](https://img.shields.io/cocoapods/v/AsyncTaskTrigger.svg?style=flat)](https://cocoapods.org/pods/AsyncTaskTrigger) [![License](https://img.shields.io/cocoapods/l/AsyncTaskTrigger.svg?style=flat)](https://cocoapods.org/pods/AsyncTaskTrigger) [![Platform](https://img.shields.io/cocoapods/p/AsyncTaskTrigger.svg?style=flat)](https://cocoapods.org/pods/AsyncTaskTrigger) [![Star](https://gitee.com/kaelinda/async-task-trigger/badge/star.svg?theme=dark)](https://gitee.com/kaelinda/async-task-trigger/stargazers) ## Example To run the example project, clone the repo, and run `pod install` from the Example directory first. ## Requirements ## Installation AsyncTaskTrigger is available through [CocoaPods](https://cocoapods.org). To install it, simply add the following line to your Podfile: ```ruby pod 'AsyncTaskTrigger' ``` ## 使用方法 ### 预置任务组信息 【推荐方案】 * 携带Handler ``` // 标识任务组的唯一ID NSString *groupKey = @"serial_group_on"; // 准备任务组 groupKey 和 任务类型 (AsyncType) // AsyncType 串行 : LXTaskAsyncTypeSerial 并发 : LXTaskAsyncTypeConcurrent [[AsyncTaskTrigger shareTrigger] prepareTaskGroupWithAsyncType:LXTaskAsyncTypeConcurrent groupKey:groupKey]; // 添加任务A [trigger addTaskHandlerAction:^(LXTaskActionBlock _Nullable semaphoreHandle) { [self actionBlockAWithComplet:^{ semaphoreHandle(); }]; } groupKey:groupKey]; // 添加任务B [trigger addTaskHandlerAction:^(LXTaskActionBlock _Nullable semaphoreHandle) { [self actionBlockBWithComplet:^{ semaphoreHandle(); }]; } groupKey:groupKey]; // 启动任务组内的任务 [trigger startTaskActionWithGroupKey:groupKey completBlock:^{ NSLog(@"kael -- 所有的任务都完成了"); }]; ``` * 不携带Handler ``` // 标识任务组的唯一ID NSString *groupKey = @"serial_group_on"; // 准备任务组 [[AsyncTaskTrigger shareTrigger] prepareTaskGroupWithAsyncType:LXTaskAsyncTypeConcurrent groupKey:groupKey]; // 添加任务A [trigger addTaskAction:^{ [self actionBlockAWithComplet:^{ // 需要在任务完成处 手动调用此方法!!! [[AsyncTaskTrigger shareTrigger] sendSemaphoreToGroupKey:groupKey]; }]; } groupKey:groupKey]; // 添加任务B [trigger addTaskAction:^{ [self actionBlockBWithComplet:^{ [[AsyncTaskTrigger shareTrigger] sendSemaphoreToGroupKey:groupKey]; }]; } groupKey:groupKey]; // 启动任务组内的任务 [trigger startTaskActionWithGroupKey:groupKey completBlock:^{ NSLog(@"kael -- 所有的任务都完成了"); }]; ``` ### 无预置信息 ``` // ---------1、获取触发器单利 AsyncTaskTrigger *trigger = [AsyncTaskTrigger shareTrigger]; __weak typeof (&*trigger)wtrigger = trigger; // 每一组任务 都需要有一个GroupKey NSString *groupKey = @"serial_group_serial"; // --------添加任务A [trigger addTaskAction:^{ // 开始执行任务A [self actionBlockAWithComplet:^{ // 任务完成后 需要向指定 groupKey 对应的任务组 发送信号量; [wtrigger sendSemaphoreToGroupKey:groupKey]; // 如果某些异步任务是通过代理的方式回调 可以在完成处这样标记下 // [[AsyncTaskTrigger shareTrigger]sendSemaphoreToGroupKey:groupKey]; }]; } asyncType:LXTaskAsyncTypeSerial groupKey:groupKey completBlock:^{ // 本次任务完成后的回调 --- 这里的回调是任务内的同步部分完成后的回调 // 如果是请求 代表是请求已发送 而非 请求已结束 }]; // -----------添加任务B [trigger addTaskAction:^{ // 执行任务B [self actionBlockBWithComplet:^{ [wtrigger sendSemaphoreToGroupKey:groupKey]; }]; } asyncType:LXTaskAsyncTypeSerial groupKey:groupKey completBlock:nil]; // Block回调发送信号量 另外一种方式 [trigger addTaskHandlerAction:^(LXTaskActionBlock _Nullable semaphoreHandle) { [self actionBlockAWithComplet:^{ // 可以直接在这里调用这个Block即可 semaphoreHandle(); }]; } asyncType:LXTaskAsyncTypeSerial groupKey:groupKey completBlock:nil]; [trigger startTaskActionWithGroupKey:groupKey completBlock:^{ NSLog(@"kael -- 所有的任务都完成了"); }]; ``` #### 异步任务Handler方式 ``` [trigger addTaskHandlerAction:^(LXTaskActionBlock _Nullable semaphoreHandle) { [self actionBlockAWithComplet:^{ // 可以直接在这里调用这个Block即可 semaphoreHandle(); }]; } asyncType:LXTaskAsyncTypeSerial groupKey:groupKey]; ``` #### 异步任务Block方式回调处理 ``` [[AsyncTaskTrigger shareTrigger] addTaskAction:^{ // 执行任务B [self actionBlockBWithComplet:^{ [[AsyncTaskTrigger shareTrigger] sendSemaphoreToGroupKey:groupKey]; }]; } asyncType:LXTaskAsyncTypeSerial groupKey:groupKey]; ``` #### 异步任务代理方式回调处理 ``` [[AsyncTaskTrigger shareTrigger] addTaskAction:^{ // 执行任务B [self actionBlockB]; } asyncType:LXTaskAsyncTypeSerial groupKey:groupKey]; // 执行任务B 完成后的代理回调 - (void)actionCompleteHanlder { // 需要告知触发器 [[AsyncTaskTrigger shareTrigger] sendSemaphoreToGroupKey:groupKey]; } ``` ## 案例分析 ### 初衷案例 本工具是为了解决两类问题: * 第一类:串行异步任务管理。 > 多个网络请求串行 a-->b-->c-->刷新UI * 第二类:并发异步任务。 > A、B、C 三个异步请求结束后,再处理数据+刷新UI 避免频繁刷新UI、避免该取数据时取不到 或者数据不全 ### 灵活运用搭配任务组 本工具的`groupKey`是一个任务组ID的概念,里面的任务必须是同一任务类型。 ``` /// 任务类型枚举 typedef NS_ENUM(NSUInteger, LXTaskAsyncType) { /// 串行 异步任务 LXTaskAsyncTypeSerial = 0, /// 并发异步任务 LXTaskAsyncTypeConcurrent = 1, }; ``` 如果过实现下面场景:A、B 异步任务并发结束后执行异步任务 C ,C任务执行完毕后再执行 并发的任务D、E,D、E任务都结束后执行任务F。 > 可以如此: ``` // 分配任务A、B到同一个任务组 - (void)firstTaskGroup { NSString *groupKey = @"groupKey_first"; // 添加任务A [[AsyncTaskTrigger shareTrigger] addTaskAction:^{ [self actionBlockAWithComplet:^{ [[AsyncTaskTrigger shareTrigger] sendSemaphoreToGroupKey:groupKey]; }]; } asyncType:LXTaskAsyncTypeConcurrent groupKey:groupKey completBlock:nil]; // 添加任务B [[AsyncTaskTrigger shareTrigger] addTaskAction:^{ [self actionBlockBWithComplet:^{ [[AsyncTaskTrigger shareTrigger] sendSemaphoreToGroupKey:groupKey]; }]; } asyncType:LXTaskAsyncTypeConcurrent groupKey:groupKey completBlock:nil]; // 开启 [[AsyncTaskTrigger shareTrigger] startTaskActionWithGroupKey:groupKey completBlock:^{ // 执行任务C [self actionBlockCWithComplet:^{ [self secondTaskGroup]; }]; }]; } // 分配任务 D、E 到同一个任务组 最后执行F - (void)secondTaskGroup { // 这里一定要记得 更改任务组ID NSString *groupKey = @"groupKey_second"; // 添加任务D [[AsyncTaskTrigger shareTrigger] addTaskAction:^{ [self actionBlockDWithComplet:^{ [[AsyncTaskTrigger shareTrigger] sendSemaphoreToGroupKey:groupKey]; }]; } asyncType:LXTaskAsyncTypeConcurrent groupKey:groupKey completBlock:nil]; // 添加任务E [[AsyncTaskTrigger shareTrigger] addTaskAction:^{ [self actionBlockEWithComplet:^{ [[AsyncTaskTrigger shareTrigger] sendSemaphoreToGroupKey:groupKey]; }]; } asyncType:LXTaskAsyncTypeConcurrent groupKey:groupKey completBlock:nil]; // 开启 [[AsyncTaskTrigger shareTrigger] startTaskActionWithGroupKey:groupKey completBlock:^{ // 执行任务F [self actionBlockFWithComplet:^{ // 最终任务执行完毕 }]; }]; } ``` ## 注意事项 * GroupKey 标记了同一组相同任务类型的 异步任务 groupKey ``` /// 添加任务 /// @param actionBlock 任务事件 /// @param asyncType 异步类型 串行 还是 并发 /// @param groupKey 任务组Key /// @param completBlock (同步部分)任务完成后的回调 - (void)addTaskHandlerAction:(LXSemaphoreBlock)actionBlock asyncType:(LXTaskAsyncType)asyncType groupKey:(NSString *)groupKey completBlock:(LXTaskActionBlock)completBlock; ``` * 任务类型 ``` /// 任务类型 typedef NS_ENUM(NSUInteger, LXTaskAsyncType) { /// 串行 异步任务 LXTaskAsyncTypeSerial = 0, /// 并发异步任务 LXTaskAsyncTypeConcurrent = 1, }; ``` ## Author Kael, zhouzuosong_kael@163.com ## License AsyncTaskTrigger is available under the MIT license. See the LICENSE file for more info.