Utilizzare un closure
. Lasciate che vi mostri un semplice esempio
// JavaScript on Client-Side
window.onload = function() {
var f = (function() {
for (i = 0; i < 3; i++) {
(function(i){
var xhr = new XMLHttpRequest();
var url = "closure.php?data=" + i;
xhr.open("GET", url, true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
console.log(xhr.responseText); // 0, 1, 2
}
};
xhr.send();
})(i);
}
})();
};
// Server-Side (PHP in this case)
<?php
echo $_GET["data"];
?>
Nel tuo caso ... avvolgere la chiamata/funzione asincrona con una chiusura
for (var i=0; i< this.selectedAvailableUnits.length; i++) {
(function(i) { // <--- the catch
var unit = this.selectedAvailableUnits[i];
var unitId = unit.unitId;
var url = '/incident/' + currentIncidentId + '/assignUnit/' + unitId
$http.post(url).then(function(response) {
// DOING SOMETHING
}, function(error) {
alert(error);
});
})(i); // <---- (the i variable might be omitted if it's not needed)
}
La sezione di seguito non è direttamente correlata alla domanda ma piuttosto ai commenti relativi a questa risposta.
L'esempio presentato il jsFiddle citato nei commenti e mostrato sotto è pieno di bug e come tale non prova niente.
È vero che questo frammento, anche se non si utilizza una chiusura, produce "Hello Kitty" tre volte; in realtà, se si sostituisce il metodo console.log()
con uno alert()
si vedrà che produce "Hello Kitty" sei, nove o anche dodici volte. Quindi, che diavolo sta succedendo?) Come è possibile ottenere la finestra di avviso spuntando sei, nove o dodici volte in un ciclo di tre iterazioni ?!
// your example (a) // my comments
//
var f = (function() {
for (i = 0; i < 3; i++) {
//(function(){ // this way you can't have multiple scopes
var xhr = new XMLHttpRequest();
var url = "closure.php?data=your-data"; // use /echo/html/ for testing on jsfiddle.net
xhr.open("GET", url, true); // use POST for testing on jsfiddle.net
xhr.onreadystatechange = function() { // this way you might catch all readyStage property values
callback(); // this way the callback function will be called several times
};
xhr.send();
//})();
}
})();
var callback = function() {
console.log("Hello Kitty"); // or use alert("Hello Kitty");
};
uscita:
GET http://fiddle.jshell.net/_display/closure.php?data=your-data 404 (NOT FOUND)
(9) Hello Kitty
Come si può vedere, abbiamo un errore e nove uscite 'Ciao Kitty' di fila :) prima che cambi la funzione di cui sopra vediamo due importanti cosa
First
onreadystatechange
negozi di eventi una funzione o un riferimento da chiamare automaticamente ogni volta che la proprietà readyState
cambia mentre la proprietà status
mantiene lo stato dell'oggetto XMLHttpRequest.
readyState
immobili valori possibili
- 0: non richiesta inizializzate
- 1: connessione server stabilita
- 2: richiesta ricevuta
- 3: elaborazione richiesta
- 4: richiedere finito e risposta è pronto
status
proprietà valori possibili
- 200: OK
- 404: Pagina non trovata
Seconda
Come ho detto nei commenti, jsfiddle.net non è affidabile per test di snippet asincroni senza alcune modifiche. In altre parole, il metodo GET
deve essere modificato in POST
e la proprietà url
deve essere modificato a questo link /echo/html/
(per ulteriori opzioni di dare un'occhiata a jsFiddle documentation)
Ora, cambiamo l'esempio di cui sopra (e seguire i commenti all'interno del codice)
// corrected example (b)
//
var f = (function() {
for (i = 0; i < 3; i++) {
//(function(i){ // uncomment this line for the 3rd output
var xhr = new XMLHttpRequest();
var url = "/echo/html";
var data = "data";
xhr.open("POST", url, true);
xhr.onreadystatechange = function() {
//if (xhr.readyState == 4 && xhr.status == 200) { // uncomment this line for the 4th output
callback(i, xhr.readyState); // uncomment this line for the 4th output
//}
};
xhr.send(data);
//})(i); // uncomment this line for the 3rd output
}
})();
var callback = function(i, s) {
console.log("i=" + i + " - readyState=" + s + " - Hello Kitty");
};
prima uscita: // sei uscite
(4) i=3 - readyState=1 - Hello Kitty // four outputs related to readyState value 'server connection established'
i=3 - readyState=2 - Hello Kitty // related to readyState value 'request received'
i=3 - readyState=4 - Hello Kitty // related to readyState value 'request finished and response is ready'
2a uscita: // sei uscite
(2) i=3 - readyState=1 - Hello Kitty // two outputs related to readyState value 'server connection established'
i=3 - readyState=2 - Hello Kitty // related to readyState value 'request received'
(3) i=3 - readyState=4 - Hello Kitty // three outputs related to readyState value 'request finished and response is ready'
Senza le modifiche apportate nell'esempio (b), abbiamo due uscite diverse. Come puoi vedere, diversi output per diversi valori di proprietà readyState sono stati resi. Ma il valore di i
è rimasto invariato.
3a uscita: // dopo decommentando le linee per la 3a uscita showned sopra nell'esempio (b)
i=0 - readyState=2 - Hello Kitty // related to readyState value 'request received'
i=0 - readyState=4 - Hello Kitty // related to readyState value 'request finished and response is ready'
i=1 - readyState=2 - Hello Kitty // ...
i=1 - readyState=4 - Hello Kitty // ...
i=2 - readyState=2 - Hello Kitty
i=2 - readyState=4 - Hello Kitty
Così, dopo uncommenting la funzione che tiene i
come argomento, vediamo che il valore di i
è stato salvato. Ma questo è ancora errato poiché ci sono sei uscite e ne abbiamo bisogno solo tre. Come non abbiamo bisogno di tutti i valori della readyState
o status
proprietà dell'oggetto XMLHttpRequest
, cerchiamo di rimuovere il commento le due righe necessarie per la quarta uscita
4 ° uscita: // dopo decommentando le linee per l'uscita 4 ° showned sopra nella esempio (b) - infine tre uscite
i=0 - readyState=4 - Hello Kitty
i=1 - readyState=4 - Hello Kitty
i=2 - readyState=4 - Hello Kitty
Infine, questo dovrebbe essere la versione corretta del frammento e questo è ciò che dobbiamo.
Un altro meccanismo onnipotente onnipotente (come ho detto in precedenza) sarebbe la funzione bind()
che non preferisco poiché è più lenta di una chiusura.
è possibile controllare la scheda della rete del browser, che viene inviata una sola richiesta? – harishr
@ Mr-domanda per favore prenditi il tuo tempo per rivedere le risposte e scegliere quello corretto – domokun