I have a problem with the following code, I want to run within a cycle for a call $ .ajax until the exit condition of the cycle is fulfilled , however the cycle does all its iterations and in the final iteration execute the ajax.
According to what I understand, your objective is that for each iteration execute an ajax request. And what you get, is that your code makes the request in the last iteration. Before continuing, the following is important:
JavaScript is an asynchronous language, which means that there is no fixed execution order that you can trust. Not all language features are blocking, there are some that do, but the vast majority do not. as is the case with ajax requests.
You will always find that you are running processes in parallel and you do not know how to act. In ES5, it was very common to see this type of programmer errors that came from non-functional languages. With the arrival of ES6 you solve much of this problem with the help of Promises , block scopes and in the next version, Async/Await .
ES5
The solution before ES6 + was to use a closure inside the loop to create a scope for the control variable:
for (var s of streamers) {
(function(s) {
$.ajax({
url: 'https://api.twitch.tv/kraken/streams/${s}?client_id=1t2i1eidglzctkjlx1xckdtguuj0y2z',
type: 'GET',
dataType: 'jsonp',
jsonCallback: 'twitchcallback'
})
.done(data => {
console.log('Streamer ${s} complete');
console.log(data);
if (s === streamers[streamers.length - 1]) {
alert('finished');
}
});
})(s);
}
Demo
ES6
Solving it in ES6 is much simpler. It is enough to use a local scope instead of a global one as it is var
:
for (let s of streamers) {
$.ajax({
url: 'https://api.twitch.tv/kraken/streams/${s}?client_id=1t2i1eidglzctkjlx1xckdtguuj0y2z',
type: 'GET',
dataType: 'jsonp',
jsonCallback: 'twitchcallback'
})
.done(data => {
console.log('Streamer ${s} complete');
console.log(data);
if (s === streamers[streamers.length - 1]) {
alert('finished');
}
});
}
Demo
ES Next: Async / Await
With async await you can control the flow much more naturally if you come from non-functional languages. The code written with async/await
is still asynchronous even if we write it synchronously.
Note: To use await
you must be in a function marked with async
(async () => {
for (let s of streamers) {
const data = await (
$.ajax({
url: 'https://api.twitch.tv/kraken/streams/${s}?client_id=1t2i1eidglzctkjlx1xckdtguuj0y2z',
type: 'GET',
dataType: 'jsonp',
jsonCallback: 'twitchcallback'
})
);
console.log('Streamer ${s} complete');
console.log(data);
if (s === streamers[streamers.length - 1]) {
alert('finished');
}
}
})();
Demo
If you decide to use the third form you should use babel :
babel archivo.js destino.js