20219: Replace API & websocket log loading with webdav polling
[arvados-workbench2.git] / src / common / use-async-interval.ts
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 var react = require("react");
6
7 export const useAsyncInterval = function (callback, delay) {
8     const savedCallback = react.useRef();
9     const active = react.useRef(false);
10
11     // Remember the latest callback.
12     react.useEffect(() => {
13         savedCallback.current = callback;
14     }, [callback]);
15     // Set up the interval.
16     react.useEffect(() => {
17         // useEffect doesn't like async callbacks (https://github.com/facebook/react/issues/14326) so create nested async callback
18         (async () => {
19             // Make tick() async
20             async function tick() {
21                 if (active.current) {
22                     // If savedCallback is not set yet, no-op until it is
23                     savedCallback.current && await savedCallback.current();
24                     setTimeout(tick, delay);
25                 }
26             }
27             if (delay !== null) {
28                 active.current = true;
29                 setTimeout(tick, delay);
30             }
31         })(); // Call nested async function
32         // We return the teardown function here since we can't from inside the nested async callback
33         return () => {active.current = false;};
34     }, [delay]);
35 };