Home > front end >  Convert serial chain of promise returning functions to async/await
Convert serial chain of promise returning functions to async/await

Time:12-26

I'm trying to translate a code from Promise returning one to async/await. My example code has 2 classes.

Example code

First one, TestAsync, functions are async. This class prints 2 first, then 1. Which means they run parallel and doesn't wait for the first one to finish.

class TestAsync {
    private async f1(n: any) {
        setTimeout(() => {
            console.log("Async 1: "   n);
            return n;
        }, 1500);
    }

    private async f2(n: any) {
        setTimeout(() => {
            console.log("Async 2: "   n);
            return n;
        }, 1000);
    }

    public async f() {
        await this.f1(1)
        await this.f2(2);
    }
}

In the second one, TestPromise, functions return Promises without async fucntions. This class prints 1 first, then 2. That's what I expected (waiting for the first one to finish) also the TestAsync should do.

class TestPromise {
    private f1(n: any) {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve(n);
                console.log("Promise 1: "   n);
            }, 1500);
        });
    }

    private f2(n: any) {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve(n);
                console.log("Promise 2: "   n);
            }, 1000);
        });
    }

    public async f() {
        await this.f1(1);
        await this.f2(2);
    }
}

How can I make TestAsync function to behave like TestPromise?

CodePudding user response:

async/await are mostly syntactic sugar around promises. So when dealing with APIs that are not marked as async or returning a promise - such as setTimeout in your example -, they'll still need to be converted into promises.

In your TestAsync example, the functions don't return anything so await doesn't have anything to wait for.

You might want to run callback-based functions through promisify or use the new timers promise API in Node.js: https://nodejs.org/api/timers.html#timers-promises-api Then they can be used in conjunction with await.

CodePudding user response:

the error is that you are not waiting for setTimeout to finish, you need to wrap it in a promise and await for it.

function wait(t) {
    return new Promise(resolve => setTimeout(resolve, t));
}
class TestAsync {
    async f1(n) {
        await wait(1500);
        console.log("Async 1: "   n);
        return n;
    };

    async f2(n) {
        await wait(1000);
        console.log("Async 2: "   n);
        return n;
    };

    async f() {
        await this.f1(1)
        await this.f2(2);
    };
}

new TestAsync().f()

  • Related