From 0862177e1d42b91962254a9024763315f5c53630 Mon Sep 17 00:00:00 2001 From: daishi Date: Thu, 28 Nov 2019 17:46:09 +0900 Subject: [PATCH] useAsyncCombineRace can no longer base on useAsyncCombineAll --- CHANGELOG.md | 10 +++++--- src/use-async-combine-race.js | 46 ++++++++++++++++++++++++++++++++--- 2 files changed, 48 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1794a2d..61a0f88 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,14 +1,16 @@ # Change Log ## [Unreleased] +### Changed +- Fix useAsyncCombineRace which was totally broken in v3.8.0 ## [3.8.0] - 2019-11-26 ### Changed - Fix inifinite loop in edge cases by avoiding slow memoization - Fix useAsyncRun for some cases with conditional running - Fix typings which are broken in #31 - - The state now has the aborted flag. - - This is technically a breaking change, but releasing it as a minor update. + - The state now has the aborted flag + - This is technically a breaking change, but releasing it as a minor update - Fix typings around Args ## [3.7.0] - 2019-11-09 @@ -70,7 +72,7 @@ ## [2.1.0] - 2019-04-16 ### Changed -- Fix a fatal bug in type definition. +- Fix a fatal bug in type definition - Update dependencies (incl. core-js@3) ## [2.0.0] - 2019-03-21 @@ -87,7 +89,7 @@ ## [1.2.0] - 2019-02-23 ### Changed - Rename useMemoSafe to useMemoPrev - - Although this is technically a breaking change, we release it as a minor update. + - Although this is technically a breaking change, we release it as a minor update ## [1.1.0] - 2019-02-18 ### Changed diff --git a/src/use-async-combine-race.js b/src/use-async-combine-race.js index 472fcfa..8ff211d 100644 --- a/src/use-async-combine-race.js +++ b/src/use-async-combine-race.js @@ -1,9 +1,24 @@ -import { useEffect } from 'react'; +import { useCallback, useEffect, useMemo } from 'react'; -import { useAsyncCombineAll } from './use-async-combine-all'; +import { useAsyncTask } from './use-async-task'; +import { useMemoList } from './utils'; export const useAsyncCombineRace = (...asyncTasks) => { - const task = useAsyncCombineAll(...asyncTasks); + const memoAsyncTasks = useMemoList(asyncTasks, (a, b) => a.start === b.start); + const task = useAsyncTask(useCallback( + async (abortController) => { + abortController.signal.addEventListener('abort', () => { + memoAsyncTasks.forEach((asyncTask) => { + asyncTask.abort(); + }); + }); + // start everything + memoAsyncTasks.forEach((asyncTask) => { + asyncTask.start(); + }); + }, + [memoAsyncTasks], + )); const finishedIndex = asyncTasks.findIndex(({ pending }) => !pending); useEffect(() => { // if there's one task finished, abort all the others @@ -15,5 +30,28 @@ export const useAsyncCombineRace = (...asyncTasks) => { }); } }); - return task; + const taskAborted = asyncTasks.every(({ aborted }) => aborted); + const taskPending = asyncTasks.every(({ pending }) => pending); + const taskError = asyncTasks.find(({ error }) => error); + const taskErrorAll = useMemoList(asyncTasks.map(({ error }) => error)); + const taskResult = useMemoList(asyncTasks.map(({ result }) => result)); + return useMemo(() => ({ + start: task.start, + abort: task.abort, + started: task.started, + aborted: taskAborted, + pending: taskPending, + error: taskError, + errorAll: taskErrorAll, + result: taskPending ? null : taskResult, + }), [ + task.start, + task.abort, + task.started, + taskAborted, + taskPending, + taskError, + taskErrorAll, + taskResult, + ]); };