最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

reactjs - JavaScript (React): How to extend async function's await to a given time - Stack Overflow

programmeradmin1浏览0评论

I would like to have a async function that sends a request to a server and awaits the response. It will then wait upto 1000ms to ensure that an animation has played out. i was wondering if I could bine these 2 tasks somehow so they add up to having waited 1000ms in total dynamically.

My current code:

const loadingHandler = async (func, target) => {
        setIsLoading(true);

        await new Promise(r => setTimeout(r, 1000));
        await func(target);

        setIsLoading(false);
    };

Some examples to further explain what exactly I mean: the function calls func() and gets a response after (lets say) 200ms. Now the timeout is only supposed to be 800ms. If the func() returns after 20ms the timeout is supposed to be 980ms. If func() takes longer than 1000ms it should continue immedietly after getting the response and not wait additionally. So is something like this 'stretcher await function' possible?

I would like to have a async function that sends a request to a server and awaits the response. It will then wait upto 1000ms to ensure that an animation has played out. i was wondering if I could bine these 2 tasks somehow so they add up to having waited 1000ms in total dynamically.

My current code:

const loadingHandler = async (func, target) => {
        setIsLoading(true);

        await new Promise(r => setTimeout(r, 1000));
        await func(target);

        setIsLoading(false);
    };

Some examples to further explain what exactly I mean: the function calls func() and gets a response after (lets say) 200ms. Now the timeout is only supposed to be 800ms. If the func() returns after 20ms the timeout is supposed to be 980ms. If func() takes longer than 1000ms it should continue immedietly after getting the response and not wait additionally. So is something like this 'stretcher await function' possible?

Share Improve this question edited Nov 25, 2021 at 15:36 Sokker asked Nov 25, 2021 at 15:32 SokkerSokker 1502 silver badges17 bronze badges 2
  • What if func() takes 2500ms? Should loadingHandler wait for that long or only be capped to 1000ms? – VLAZ Commented Nov 25, 2021 at 15:33
  • @VLAZ if it takes longer than 1000ms it shouldnt wait additionaly and continue immediately after getting the response. Also: no cap on the waiting time – Sokker Commented Nov 25, 2021 at 15:34
Add a ment  | 

3 Answers 3

Reset to default 4

Sure, just remember how long it's been so far, then delay that much longer:

const loadingHandler = async (func, target) => {
    setIsLoading(true);

    const started = Date.now();
    await func(target);
    const elapsed = Date.now() - started;
    const delayFurther = 1000 - elapsed;
    if (delayFurther > 0) {
        await new Promise(r => setTimeout(r, delayFurther));
    }

    setIsLoading(false);
};

That said, holding up the user because an animation hasn't finished might not be the best UX. Perhaps you could make the animation finish more quickly when func is already done. (Humans tend to notice delays > about 80-100ms, a bit less when we're younger.)

An alternative to Mr Crowder's perfectly valid solution: Rather than wait for the promise to finish and then checking if we need to start a new one, start two promises at the same time and wait for them both. Has the same effect, but makes the code shorter:

const loadingHandler = async (func, target) => {
  setIsLoading(true);
  await Promise.all([
    func(target),
    new Promise(r => setTimeout(r, 1000)),
  ]);
  setIsLoading(false);
}

In your code you starts first promise (interval), waits for it to finish, then starts second (func) and wait to finish. You should start both promises and wait for it together.

const loadingHandler = async (func, target) => {
        setIsLoading(true);

        const p1 = new Promise(r => setTimeout(r, 1000));
        const p2 = func(target);
    
        await Promise.all([p1,p2]);

        setIsLoading(false);
    };
发布评论

评论列表(0)

  1. 暂无评论