0

I write a function like bellow

function test() {
apiCall.ajaxCallWithReturnData(obj, 'GET', 'url')
    .then(res => {
        var metrics

        metrics = res.Data.map((d) => { //filling metrics array
            return {
                MetricID: d.MetricID,
                Metric: d.Metric
            }
        })
        weeklyChartdata(null, 'Overall') //call method for default metric
            .then(result => {
                console.log('start')

            })
            .then(() => {
                //console.log(scors)

                metrics.forEach(function (m, i) {//Loop each metric
                    console.log('loop' + i)

                    weeklyChartdata(m.MetricID, m.Metric)
                        .then(result => {
                            console.log('loop' + i + 'result', result.scors)
                        })

                })//Loop each metric                     

            })
            .then(() => {
                console.log('done')
            })

    })

}

with above code I expect a result like bellow order

start

loop0
loop 0 result 
loop1
loop 1 result 
loop2
loop 2 result 

done

but result is generate like bellow order

start
loop0
loop1
loop2
done
loop 0 result 
loop 1 result 
loop 2 result 

I understand the metrics.forEach moving forward and not wait for rest code execution . please suggest me how I handle this situation ,to wait loop until all code executed.

kuntal
  • 1,591
  • 2
  • 16
  • 36

2 Answers2

0

I believe you are looking for Promise.all()

metrics.forEach(function (m, i) {//Loop each metric
                console.log('loop' + i)

                weeklyChartdata(m.MetricID, m.Metric)
                    .then(result => {
                        console.log('loop' + i + 'result', result.scors)
                    })

            })//Loop each metric      

becomes (not tested)

        const promises = [];
        metrics.forEach((m, i) => {//Loop each metric
                console.log('loop' + i)

           promises.push(weeklyChartdata(m.MetricID, m.Metric)
                    .then(result => {
                        console.log('loop' + i + 'result', result.scors)
                        return result;
                    })
           )  

        })//Loop each metric
        Promise.all(promises).then((results) => {
          console.log(results);
        });

Hope this helps (see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all).

Note: the order of console.logs does not really matter, it's about your results in the Promis.all promise

user3791775
  • 426
  • 3
  • 5
0

Promise.all is a perfectly fine way of achieving this, as answered by user3791775. I am presenting another way.

forEach does not work well with async functions. You could use for-of loop instead. So your metric.forEach should be like the code below (Not tested)

let i=0;
for (const m of metrics){
  console.log('loop' + i)
  weeklyChartdata(m.metricID, m.metric)
  .then(result => {
      console.log('loop' + i + 'result', result.scors)
  })
  i++;
}
Rachit Anand
  • 616
  • 5
  • 16