使用AngularJs时,使用forEach循环时,循环外的变量仍为0: 解释我的问题,这是我的代码
var totald=0;
children.forEach(function (child) {
fetchdata(child['id']).then(function (resp) {
totald+= resp.total;
domaines.push({'id': child['id'], 'total': resp.total, 'details': resp.details});
});
});
在forEach之后,当我执行console.log(totald)时,我得到0.但是当我将console.log放在forEach中时,变量totald会递增。
如何解决问题并在forEach完成后获得正确的totald值
答案 0 :(得分:4)
您可以将每个承诺映射为列表,并使用$q.all
等待所有承诺。
这样的事情:
var totald = 0;
var promises = children.map(function (child) {
return fetchdata(child['id']).then(function(response){
return { id: child['id'], response: response };
});
});
$q.all(promises).then(function(results)){
results.forEach(function(result){
totald += result.response.total;
domaines.push({'id': result.id, 'total': result.response.total, 'details': result.response.details});
});
};
答案 1 :(得分:1)
您应该考虑以功能样式重写此代码;它会更具可读性:
const promises = children.map(async (child) => {
const response = await fetchdata(child['id']);
return {
id: child['id'],
response
};
});
const results = await Promise.all(promises);
const total = results.map(result => result.response.total)
.reduce((x, y) => x + y, 0);
const domains = results.map(result => ({
id: result.id,
total: result.response.total,
details: result.response.details
});
最重要的变化是使用map
而不是forEach
。使用forEach
从来没有真正的理由,因为for (... of ...)
构造更清楚地表明了副作用。 map
也更紧凑:
const ys = xs.map(x => x + 1);
vs ...
const ys = [];
xs.forEach(x => {
ys.push(x + 1);
})
如果您担心async-await的浏览器支持,那么您可以使用Babel + Webpack。
答案 2 :(得分:0)
您可以使用Promise.all:
var total = 0;
Promise.all(
children.map(function(c) { return fetchdata(child['id']); })
).then(function(datas) {
datas.forEach(function(data) {
total += data.total;
domaines.push({'id': child['id'], 'total': data.total, 'details': data.details});
});
});