反应钩子等待上一个调用完成



我正在研究一个使用钩子的反应项目。我被分配了一个任务

"更改useInterval钩子,或创建一个新钩子(usePoll?(。这应该与useInterval相同,但应等到ajax请求完成后再启动计时器"。

我是反应钩子的新手,正在寻找解决方案,但找不到。当前useInterval功能如下。

import React, { useEffect, useRef } from 'react';
export function useInterval(callback, delay, immediate = true) {
    const savedCallback = useRef();
    // Remember the latest callback.
    useEffect(() => {
        savedCallback.current = callback;
    }, [callback]);
    // Set up the interval.
    useEffect(() => {
        function tick() {
            savedCallback.current();
        }
        if (delay !== null) {
            if (immediate) {
                tick();
            }
            let id = setInterval(tick, delay);
            return () => clearInterval(id);
        }
    }, [delay]);
}

它在程序中的使用如下。

useInterval(() => {
        get(`/api/v1/streams/1`).then(({ data: { data } }) => {
            setStream(data);
        });
    }, 5000);

我需要更改 useInterval 函数以等到 ajax 请求完成后再启动计时器。如果有人能在这方面帮助我,那就太好了。谢谢

试一试......它需要在then内部调用next函数,但它应该接近你要找的东西。

function useInterval(handler, delay, immediate = true) {
  React.useEffect(() => {
    let interval
    const start = () => {
      clearInterval(interval)
      interval = setInterval(() => handler(start), delay)
    }
    handler(start)
    return () => clearInterval(interval)
  }, [])
}

用法:

useInterval((next) => {
    get('/api/v1/streams/1').then(data => {
        // tell the timer to begin
        next()
    })
}, 5000)
您可以使用

asyncawait来等待首次调用完成。

像这样修改内部useEffect

export function useInterval(callback, delay, immediate = true) {
    const savedCallback = useRef();
    // Remember the latest callback.
    useEffect(() => {
        savedCallback.current = callback;
    }, [callback]);
    // Set up the interval.
    useEffect(() => {
        // useEffect doesn't like async callbacks (https://github.com/facebook/react/issues/14326) so create nested async callback
        (async () => { 
            // Make tick() async
            async function tick() {
                await savedCallback.current();
            }
            if (delay !== null) {
                if (immediate) {
                    await tick();  // Here we should await for tick()
                }
                let id = setInterval(tick, delay);  // Unfortunately setInterval is not async/await compatible. So it will not await for tick
                return () => clearInterval(id);
           }
        })(); // Call nested async function
    }, [delay]);

}

并且您的回调应该返回Promise以便asyncawait正常工作

useInterval(() => {
    // After .then promise will be resolved, so our useInterval will know about that
    return get(`/api/v1/streams/1`).then(({ data: { data } }) => {
        setStream(data);
    });
}, 5000);

相关内容

  • 没有找到相关文章

最新更新