Reputation: 1677
I have an Array of elements and I need to loop over them getting a value from a server at each pass. With the following code I am getting all the results mixed, due to the asynchronous call in the forEach loop. I need the results to be shown in the same order as in the Array.
var en_devices= [
["72", "Device 1"],
["73", "Device 2"],
["74", "Device 3"],
["75", "Device 4"],
["76", "Device 5"],
["5158", "Device 6"]
];
en_devices.forEach(element => {
$.get('/check-energy/'+element[0], function(data){
content = "<div class='service'>"+element[1]+"</div> <div class='watt'>"+data+"</div><br/>";
$('#description-en').append(content);
});
});
Upvotes: 0
Views: 110
Reputation: 1641
If $.get
is jQuery.get() then it returns a promise and you can use asynchronous programming.
As @CherryDT said, utilize it in an async
function. If you don't have one, use it an IIFE - Immediately Invoked Function Expression:
(async () => {
for (let element of en_devices) {
const data = await $.get('/check-energy/' + element[0]);
const content = "<div class='service'>" + element[1] + "</div> <div class='watt'>" + data + "</div><br/>";
$('#description-en').append(content);
}
})();
As @huyts pointed, the above method calls the API one at time. To make it parallel, use Promise.all
:
(async () => {
const promises = en_devices.map(element =>
$.get('/check-energy/' + element[0])
.then(data => [element[1], data])
);
const results = await Promise.all(promises);
for (let result of results) {
const content = "<div class='service'>" + result[0] + "</div> <div class='watt'>" + result[1] + "</div><br/>";
$('#description-en').append(content);
}
})();
Upvotes: 2
Reputation: 1141
See Promise.all.
const en_devices= [
["72", "Device 1"],
["73", "Device 2"],
["74", "Device 3"],
["75", "Device 4"],
["76", "Device 5"],
["5158", "Device 6"]
];
const length = en_devices.length;
const promises = [];
const results = Array(length).fill(null);
en_devices.forEach((element, index) => {
promises.push(
new Promise((resolve, reject) => {
$.get('/check-energy/'+element[0], function(data){
content = "<div class='service'>"+element[1]+"</div> <div class='watt'>"+data+"</div><br/>";
results[index] = content;
resolve();
}
})
);
});
Promise.all(promises).then(() => {
for (const result of results) $('#description-en').append(result);
});
Upvotes: 0