Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript: Wait for all promises

i got a small problem with my promises.

This is my function:

public generateMealPlanForAWeek(myMealProfile: any, totalCalories:number):Promise<any> {
        return new Promise(resolve => {
            let mealplan:Array<any> = [];
            for (let i = 1; i <= 7; i++) {
                this.generateMealPlanForOneDay(myMealProfile, totalCalories).then(data => {
                    mealplan.push(data); // resolves much later
                });
            }
            resolve(mealplan); // is resolved instant
        })
    }

My problem is, that "generateMealPlanForOneDay" is resolved later then the mealplan itself.

Mealplan is an array of objects (meals in this case).

When i want to save my mealplan, the mealplan is empty:

this.storage.set('Mealplan', JSON.stringify(mealplan)).then(....) // meal plan is Array[0]

Whats the best way to resolve all meals of my meal plan and then save it?

like image 504
Fargho Avatar asked Dec 13 '16 13:12

Fargho


People also ask

Does Promise all wait for all promises?

Promise.all waits for all fulfillments (or the first rejection).

How do you wait for promises to complete?

The keyword await is used to wait for a Promise. It can only be used inside an async function. This keyword makes JavaScript wait until that promise settles and returns its result. Here is an example with a promise that resolves in 2 seconds.

How do you handle reject in promises all?

Promise. all is all or nothing. It resolves once all promises in the array resolve, or reject as soon as one of them rejects. In other words, it either resolves with an array of all resolved values, or rejects with a single error.

How do you check if all promises are resolved?

The Promise. all() method can be used to check whether all Promises have fulfilled successfully. It accepts an iterable object (e.g. an array) of multiple Promises and returns a Promise. The returned Promise is resolved if all the input Promises passed to it are resolved.


2 Answers

You can use Promise.all in this case.

public generateMealPlanForAWeek(myMealProfile: any, totalCalories:number):Promise<any> {
    var mealPlans = [];
    for (let i = 1; i <= 7; i++) {
       mealPlans.push(this.generateMealPlanForOneDay(myMealProfile, totalCalories));
    }
    return Promise.all(mealPlans);
}

// later
generateMealPlanForAWeek(...).then(mealPlans => ...);
like image 147
Daniel A. White Avatar answered Oct 07 '22 16:10

Daniel A. White


Instead of working with promises, you can also work with event streams.

The Reactive Extensions for JavaScript (RxJS, see https://github.com/ReactiveX/RxJS) makes it easy to react to event streams (Observables and their OnNextevents), or for instance to the end of an event stream (the OnCompletedevent), to collect the events and save their data.

Here's an interesting example: https://xgrommx.github.io/rx-book/content/getting_started_with_rxjs/creating_and_querying_observable_sequences/creating_and_subscribing_to_simple_observable_sequences.html

like image 43
Roy Dictus Avatar answered Oct 07 '22 16:10

Roy Dictus