Search code examples
node.jses6-promisepuppeteer

avoid passing around temporary Promise objects


I'm automating chrome using puppeteer and I find myself doing the following very often

// set up a promise that will resolve once some specific 
// network response (xhr for example) shows up
const eventPromise = checkForThing();
await page.click(SUBMIT_BUTTON);
await eventPromise;

The reason for the order is that I don't want to miss the network response that will occur as a result of the page click.

Is there a better way to do this? I don't want to have temporarily promise objects all over the place because of this. Ideally, the code should just read

await page.click()
await checkForThing();

checkForThing() looks something like

    function checkForThing(page) {       

    return new Promise((resolve, reject) => {
        function handleLoginResponse(response) {
            try {
                if (response.resourceType() === 'xhr') {
                    return;
                }
                const request = response.request();


                if (response && response.status() === 401) {
                    reject(loginFailureMessage);
                } else {
                    resolve();
                }
                page.off('response', handleLoginResponse);

            } catch (error) {
                reject(loginFailureMessage);
            }
        };

        page.on('response', handleLoginResponse);
    });
}

Solution

  • How about a simple Promise.all that awaits for both of them?

    await Promise.all([page.click(), checkForThing()])
    

    This way it will resolve finally no matter which order they are in.