简体   繁体   中英

async/await doesn't wait before executing next line in JS

I found an exponential backoff function which is supossed to retry an API fetch in case of an error in exponential delays:

async function exponentialBackoff(toTry, max, delay) {
    console.log('max', max, 'next delay', delay);
    try {
        let response = await toTry()
        return response;
    } catch (e) {
        if (max > 0) {
            setTimeout(function () {
                exponentialBackoff(toTry, --max, delay * 2);
            }, delay);

        } else {
            console.log('maximum amount of tries exceeded', e);
            return e;
        }
    }
}

I then use the function with the help of GA API library to make a request. On purpose I am sending an invalid body to make the request fail:

response = await exponentialBackoff(async function () {
                    return await gapi.client.request({
                        path: 'https://analyticsadmin.googleapis.com/v1beta/properties',
                        method: 'POST',
                        body: property
                    })
                }, 10, 30)

console.log("NEXT LINE"); 

What I would expect is that the exponential backoff will run out of all attempts (10) and only after that it would execute the console log.

What actually happens is that the console log gets executed right after first try. What am I doing wrong there?

Thank you

  1. Promisify setTimeout and await it. A promisified variant is

    function sleep(ms) { return new Promise(res => { setTimeout(res, ms); }); }
  2. await exponentialBackoff in the catch block.

The fixed code is:

function sleep(ms) { return new Promise(res => { setTimeout(res, ms); }); }

async function exponentialBackoff(toTry, max, delay) {
    console.log('max', max, 'next delay', delay);
    try {
        let response = await toTry()
        return response;
    } catch (e) {
        if (max > 0) {
            await sleep(delay);
            return await exponentialBackoff(toTry, --max, delay * 2);    
        } else {
            console.log('maximum amount of tries exceeded', e);
            return e;
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM