2012-02-20 14 views
6

Sono relativamente nuovo a JavaScript e pensavo di sapere come funzionavano le funzioni di callback ma dopo un paio d'ore di ricerche sul Web non riesco ancora a capire perché il mio codice non funzioni.Impostazione della variabile locale in una funzione di callback JavaScript

Sto facendo una richiesta AJAX che restituisce un array di stringhe. Sto cercando di impostare questo array su una variabile locale, ma sembra che perderà il suo valore non appena viene eseguita la funzione di callback.

var array; 

    $.ajax({ 
     type: 'GET', 
     url: 'include/load_array.php', 
     dataType: 'json', 
     success: function(data){ 
      array = data; 
     }, 
     error: function(jqXHR, textStatus, errorThrown){ 
      alert("Error loading the data"); 
     } 
    }); 

    console.debug(array); 

Nella console, array appare come indefinito. Qualcuno può spiegarmi perché questo non viene impostato e come è possibile impostare una variabile locale in una funzione di callback.

risposta

7

Il problema qui è che console.log viene eseguito in modo sincrono mentre la chiamata ajax viene eseguita in modo asincrono. Quindi viene eseguito prima del completamento della richiamata in modo da visualizzare ancora array come undefined perché success non è ancora stato eseguito. Per fare questo lavoro è necessario ritardare la chiamata console.log fino al completamento dello success.

$(document).ready(function() { 
    var array; 

    var runLog = function() { 
     console.log(array); 
    }; 

    $.ajax({ 
     type: 'GET', 
     url: 'include/load_array.php', 
     dataType: 'json', 
     success: function(data){ 
     array = data; 
     runlog(); 
    }}); 
}); 
+0

Penso che tu sia confuso dalla formattazione del codice. 'Console.debug' è direttamente dopo' ajax'. –

+0

Credo che l'ambito sia corretto, è solo che la formattazione è disattivata per le prime due righe non vuote (dovrebbero essere spostate a sinistra 1). – GoldenNewby

+0

@JamesMontagne hai esattamente ragione. La formattazione mi ha davvero sconvolto. Aggiornata la risposta. – JaredPar

2

Il primo A in ajax è per Asincrono, il che significa che al momento del debug della matrice, il risultato non è ancora stato consegnato. La matrice non è definita al momento della visualizzazione del suo valore. Hai bisogno di fare console.debug sotto array = data.

+0

Ah ah, sembra così ovvio ora! Esiste un'alternativa ad AJAX che raccomanderesti di garantire che il programma aspetti la risposta prima che continui l'esecuzione? – Alex

+0

È possibile effettuare chiamate http sincrone in javascript, ma non c'è motivo per cui si desideri eseguirlo. La prossima volta, inizia a lavorare con il risultato nella giusta prospettiva. – GoldenNewby

+2

Questo è SJAX. Sincrono, ovvero l'esecuzione verrà bloccata fino a quando il risultato non sarà stato recuperato. Nella tua richiesta json, se si introduce async: false, il recupero sarà sincrono - in parole semplici, il codice precedente funzionerà. Ma poi di nuovo, questa è una cattiva pratica. La scelta del codice di debug all'interno di un callback come sottolineato da GoldenNewby è la strada da percorrere. –

1

La funzione success non viene eseguita immediatamente, ma solo dopo l'arrivo della risposta HTTP. Pertanto, array è ancora undefined a questo punto. Se si desidera eseguire operazioni sui dati di risposta HTTP, farlo all'interno della funzione success o, in alternativa, definire tale operazione all'interno di una funzione e quindi richiamare tale funzione all'interno della richiamata success.

0

AJAX è asincrono. Si sta impostando la variabile array, ma solo dopo che è stato eseguito il codice debug. Effettuare una chiamata AJAX invia una richiesta ma continua nel codice. In un secondo momento, la richiesta ritorna e le tue funzioni success o error vengono eseguite.

1

Prova chiamare una funzione per impostare questa variabile dopo l'success:

var array; 

var goodToProceed = function(myArr) { 
    console.debug(myArr); 
}; 

$.ajax({ 
type: 'GET', 
url: 'include/load_array.php', 
dataType: 'json', 
success: function(data){ 
    goodToProceed(data); 
}, 
error: function(jqXHR, textStatus, errorThrown){ 
    alert("Error loading the data"); 
} 
}); 
+2

Perché preoccuparsi di creare una funzione anonima che chiama goodToProceed invece di essere chiamata direttamente in caso di successo? – GoldenNewby

+0

Sì GoldenNewby, buon punto. Lo faccio spesso ma in effetti, non c'è bisogno di farlo. – adis

+0

@adis, a volte è bello farlo, per districare il codice, tuttavia, in questo caso non è necessaria una funzione anonima. basta definire 'success: goodToProceed,' – stivlo

Problemi correlati