1

I'm having a massive issue with async await functions not working properly.

I need all my functions to run sequentially and await the return of the function prior BEFORE running the next one. But they're not doing that.

Function1:

const scrollToBottomOfPage = async (e) => {
    setTimeout(() => window.scrollTo(0, 10000), 100);

    setTimeout(() => window.scrollTo(0, 10000), 100);

    return 'Scroll To Bottom Done';
}

Function 2:

const expandButtons = async (e) => {
    await scrollToBottomOfPage();

    setTimeout(() => {
        clickSeeButton1();
        clickSeeButton2();
        clickSeeButton3();

        console.log('buttons clicked');
        return 'Buttons clicked';
    }, 1000)
}

Function 3:

getParagraphs = async (e) => {
    console.log('Get Paragraphs Started');

    let paragraphItems = [];

    // Get all paragraph items
    let paragraphsArray = document.querySelectorAll('p.text');

    if (paragraphsArray.length > 0) {
        paragraphsArray.forEach(para => {
            let newParagraph = para.innerText;

            paragraphItems.push(newParagraph);

        })
        
        console.log('Get Paragraphs done');
        return 'Get Paragraphs Done';
    }
}

Function 4 (that SHOULD call them one after another, but only when the one before it is completely done.)

getItems = async (e) => {
    await scrollToBottomOfPage();
    await expandButtons();


    await getParagraphs();

    console.log('Get Items All Done');

    return 'Get All Items Done';
}

I want scrollToBottomOfPage to go first, and ONLY AFTER IT'S completely done, then run expandButtons, and then only after it's completely done to run getParagraphs.

Here are my console.logs, which showcases the timing error:

  • Buttons clicked

  • Get paragraphs started

  • Get items all done

  • get paragraphs done

When it SHOULD BE:

  • Buttons clicked

  • Get Paragraphs started

  • Get Paragraphs done

  • get Items all done

I've tried everything including setTimeouts and that doesn't help. I don't know what I'm doing wrong.

Buckyx55
  • 434
  • 5
  • 23

1 Answers1

3

await will pause a function until the promise on the right-hand side of the statement has resolved.

const scrollToBottomOfPage = async (e) => {
    setTimeout(() => window.scrollTo(0, 10000), 100);

    setTimeout(() => window.scrollTo(0, 10000), 100);

    return 'Scroll To Bottom Done';
}

With the above code:

  1. The function is called
  2. Two calls to functions are queued with setTimeout
  3. The function returns a promise which resolves with 'Scroll To Bottom Done'
  4. The queued functions trigger after 100ms or the event loop becomes free, whichever is later

You can't just slap async on a function and expect the promise it returns to resolve only when everything asynchronous it does is finished.

You need to wait until it is "done" (by whatever definition you want to give) before resolving the promise.

You probably want to wrap each call to setTimeout in a promise and use await Promise.all([ /* those promises */ ]);


You make the same error everywhere else you use setTimeout.

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335