首页 > 解决方案 > 等待 foreach 循环以在 javascript 中执行内部异步代码

问题描述

我写了一个像下面这样的函数

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')
            })

    })

}

使用上面的代码,我希望得到类似下面的结果

start

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

done

但结果生成如下

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

我理解 metrics.forEach向前发展,而不是等待其余代码执行。请建议我如何处理这种情况,等待循环直到所有代码执行。

标签: javascriptloopsforeachpromise

解决方案


Promise.all正如 user3791775 所回答的那样,这是实现这一目标的完美方法。我正在介绍另一种方式。

forEach不适用于异步函数。你可以for-of loop改用。所以你metric.forEach应该像下面的代码(未测试)

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++;
}

推荐阅读