hardywang
hardywang

Reputation: 5162

TypeScript wait for promise.all and return result

I am writing some code in Node.Js, and use promise.all for parallel executing. To simplify the issue I use following sample code

in MyService.ts

@Injectable()
export class MyService {
    constructor(private readonly anotherService: AnotherService) { }

    public async job1(a: number): Promise<MyObject> {
        // try to calculate the result in parallel.
        const promiseArray = [];
        promiseArray.push(this.anotherService.job2(a));
        promiseArray.push(this.anotherService.job2(a + 1));
        promiseArray.push(this.anotherService.job2(a - 1));

        await Promise.all(promiseArray).then((results: MyObject[]) => {
            for (const obj of results) {
                if (obj.Index === 1) {
                    return obj;
                }
            }
        });

        return null;
    }
}

The anotherService.job2() has return type Promise<MyObject>.

I prepared my test data, set break point to return obj; and return null;, and it first stopped at return obj; then at return null;. Therefore the caller of this function gets null eventually.

If I change code to

@Injectable()
export class MyService {
    constructor(private readonly anotherService: AnotherService) { }

    public async job1(a: number): Promise<MyObject> {
        // try to calculate the result in parallel.
        const promiseArray = [];
        promiseArray.push(this.anotherService.job2(a));
        promiseArray.push(this.anotherService.job2(a + 1));
        promiseArray.push(this.anotherService.job2(a - 1));

        const results = await Promise.all(promiseArray);
        for (const obj of results) {
            if (obj.Index === 1) {
                return obj;
            }
        }

        return null;
    }
}

It works.

What is the proper way to use Promise.all and return the result from it? When shall I use Promise.all().then()?

Upvotes: 1

Views: 3340

Answers (1)

Christopher Slater
Christopher Slater

Reputation: 884

The problem with the first version of your code is you are only ever returning null for the job1 function.

You could re-write like this, take note that we are returning the result of the then:

...
        return await Promise.all(promiseArray).then((results: MyObject[]) => {
            for (const obj of results) {
                if (obj.Index === 1) {
                    return obj;
                }
            }

            return null;
        });
...

To answer your question, of when to use what when. I think that comes down to what of the two approaches you find is simplest, easiest-to-read and maintain.

I personally prefer your second approach.

Upvotes: 1

Related Questions