( tasks: S & Array<UseAsyncQueueTask<any>>, options?: UseAsyncQueueOptions, )
| 51 | * @param options |
| 52 | */ |
| 53 | export function useAsyncQueue<T extends any[], S = MapQueueTask<T>>( |
| 54 | tasks: S & Array<UseAsyncQueueTask<any>>, |
| 55 | options?: UseAsyncQueueOptions, |
| 56 | ): UseAsyncQueueReturn<{ [P in keyof T]: UseAsyncQueueResult<T[P]> }> { |
| 57 | const { |
| 58 | interrupt = true, |
| 59 | onError = noop, |
| 60 | onFinished = noop, |
| 61 | signal, |
| 62 | } = options || {} |
| 63 | |
| 64 | const promiseState: Record< |
| 65 | UseAsyncQueueResult<T>['state'], |
| 66 | UseAsyncQueueResult<T>['state'] |
| 67 | > = { |
| 68 | aborted: 'aborted', |
| 69 | fulfilled: 'fulfilled', |
| 70 | pending: 'pending', |
| 71 | rejected: 'rejected', |
| 72 | } |
| 73 | |
| 74 | const initialResult = Array.from(Array.from({ length: tasks.length }), () => ({ state: promiseState.pending, data: null })) |
| 75 | |
| 76 | const result = reactive(initialResult) as { [P in keyof T]: UseAsyncQueueResult<T[P]> } |
| 77 | |
| 78 | const activeIndex = shallowRef<number>(-1) |
| 79 | |
| 80 | if (!tasks || tasks.length === 0) { |
| 81 | onFinished() |
| 82 | return { |
| 83 | activeIndex, |
| 84 | result, |
| 85 | } |
| 86 | } |
| 87 | |
| 88 | function updateResult(state: UseAsyncQueueResult<T>['state'], res: unknown) { |
| 89 | activeIndex.value++ |
| 90 | result[activeIndex.value].data = res as T |
| 91 | result[activeIndex.value].state = state |
| 92 | } |
| 93 | |
| 94 | tasks.reduce((prev, curr) => { |
| 95 | return prev |
| 96 | .then((prevRes) => { |
| 97 | if (signal?.aborted) { |
| 98 | updateResult(promiseState.aborted, new Error('aborted')) |
| 99 | return |
| 100 | } |
| 101 | |
| 102 | if ( |
| 103 | result[activeIndex.value]?.state === promiseState.rejected |
| 104 | && interrupt |
| 105 | ) { |
| 106 | onFinished() |
| 107 | return |
| 108 | } |
| 109 | |
| 110 | const done = curr(prevRes).then((currentRes: any) => { |
no test coverage detected