1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
5 import React from "react";
7 export const useAsyncInterval = function (callback, delay) {
8 const ref = React.useRef<{cb: () => Promise<any>, active: boolean}>({
13 // Remember the latest callback.
14 React.useEffect(() => {
15 ref.current.cb = callback;
17 // Set up the interval.
18 React.useEffect(() => {
20 if (ref.current.active) {
21 // Wrap execution chain with promise so that execution errors or
22 // non-async callbacks still fall through to .finally, avoids breaking polling
23 new Promise((resolve) => {
24 return resolve(ref.current.cb());
27 // Possibly implement back-off reset
30 // Possibly implement back-off in the future
32 setTimeout(tick, delay);
37 ref.current.active = true;
38 setTimeout(tick, delay);
40 // Suppress warning about cleanup function - can be ignored when variables are unrelated to dom elements
41 // https://github.com/facebook/react/issues/15841#issuecomment-500133759
42 // eslint-disable-next-line
43 return () => {ref.current.active = false;};