2009-09-21 13 views
16

Ciao a tutti. Ho, quello che sembra essere, un problema banale. Ho il seguente JavaScript:jQuery: attendere il completamento della funzione per continuare l'elaborazione?

$(function() { 
    var r = GetResults(); 

    for(var i = 0; i < r.length; i++) { 
     // Do stuff with r 
    } 
}); 

function GetResults() { 
    $.getJSON("/controller/method/", null, function(data) { 
     return data; 
    }); 
} 

A causa del fatto che sto chiamando un metodo in modo asincrono, lo script continua esecuzione e quando incontra il ciclo for, r ovviamente non è intenzione di avere ancora un valore. La mia domanda è: quando ho un metodo che sta facendo un'operazione asincrona, e sono dipendente dai dati che ritorna nel blocco principale, come posso interrompere l'esecuzione fino a quando i dati non vengono restituiti? Qualcosa di simile:

var r = GetResults(param, function() { 

}); 

dove la funzione è una funzione di richiamata. Non riesco a spostare l'elaborazione for loop nella funzione di callback della richiesta JSON perché sto riutilizzando la funzionalità di GetResults più volte in tutta la pagina, a meno che non voglia duplicare il codice. Qualche idea?

risposta

13

sposta il blocco "do stuff with r" nel callback $ .getJSON. non puoi fare cose con r fino a quando non è stato consegnato, e la prima opportunità che dovrai usare r è nel callback ... quindi fallo allora.

$(function() { 
    var r = GetResults(); 
}); 

function GetResults() { 
    $.getJSON("/controller/method/", null, function(data) { 
     for(var i = 0; i < data.length; i++) { 
      // Do stuff with data 
     } 
     return data; 
    }); 
} 
+0

Grazie per la risposta. Il motivo per cui ho diviso GetResults è che sto riutilizzando quella funzionalità più volte in tutta la pagina. Dovrei modificare il mio post per affermarlo. – user135383

+0

se è necessario eseguire la stessa elaborazione su dati provenienti da più posizioni, basta sostituire la funzione di callback con una funzione con nome e eseguire l'elaborazione lì. $ .getJSON ("/ controller/method /", null, processData (data)); function processData (d) {...} –

3

Si potrebbe fare questo:

$(function() { 
    PerformCall();   
}); 

function PerformCall() { 
    $.getJSON("/controller/method/", null, function(data) { 
     for(var i = 0; i < data.length; i++) { 
     // Do stuff with data 
     } 
    }); 
} 
0

Questo non è possibile.

O si esegue la funzione in modo sincrono oppure si modifica il progetto del codice per supportare l'operazione asincrona.

0

Spostare il trattamento dei dati nel callback:

$(function() { 
    GetResults(); 
}); 

function GetResults() { 
    $.getJSON("/controller/method/", null, function(data) { 

     for(var i = 0; i < data.length; i++) { 
      // Do stuff with data 
     } 
    }); 
} 
+0

questo non funzionerà. la tua dichiarazione di ritorno tornerà dalla richiamata, non da GetResults. Questa soluzione non funzionerà mai in quanto non utilizza correttamente le callback – mkoryak

+0

@mkoryak Grazie. Ho rimosso il reso dalla richiamata. – ctford

7

Ajax si dà già una richiamata, si suppone di usarlo:

function dostuff(data) { 
    for(var i = 0; i < data.length; i++) { 
     // Do stuff with data 
    } 
}; 
$(document).ready(function() { 
    $.getJSON("/controller/method/", null, dostuff); 
}); 
2

La risposta breve è che non si può bloccare su un'operazione asincrona ... che è, naturalmente, il significato di "asincrono".

Al contrario, è necessario modificare il codice per utilizzare una richiamata per attivare l'azione in base ai dati restituiti dalla chiamata $.getJSON(...). Qualcosa come il seguente dovrebbe funzionare:

$(function() { 
    GetResults(); 
}); 

function GetResults() { 
    $.getJSON("/controller/method/", null, function(data) { 
    for(var i = 0; i < data.length; i++) { 
     // Do stuff with data 
    } 
    }); 
} 
2

Attribuite le vostre esigenze aggiornati ...

non riesco a spostare il ciclo per l'elaborazione nella funzione di callback della richiesta JSON perché sto riutilizzare il funzionalità di GetResults diverse ore in tutta la pagina, a meno che I voglia duplicare il codice. Qualche idea?

... è possibile modificare GetResults() ad accettare una funzione come parametro, che si sarebbe poi eseguire come $.getJSON callback (un'avvertenza relativa al codice d'aria):

$(function() { 
    GetResults(function(data) { 
     for(var i = 0; i < data.length; i++) { 
      // Do stuff with data 
     } 
    }); 
}); 

function GetResults(callback) { 
    $.getJSON("/controller/method/", null, callback); 
} 

Come si può vedere dal generale La marea di risposte, è meglio non provare a combattere il modello di programmazione jQuery asincrono.:)

0

si può avere un callback con i parametri che dovrebbero funzionare bene ...

$(function() { 
    GetResults(function(data) { 
     for(var i = 0; i < data.length; i++) { 
     // Do stuff with data 
     } 
    }); 

}); 

function GetResults(func) { 
    $.getJSON("/controller/method/", null, func); 
} 
7

ho incontrato qualcosa di simile prima. Dovrai eseguire la chiamata ajax in modo sincrono.

Ecco il mio esempio di lavoro:

$.ajax({ 
    type: "POST", 
    url: "/services/GetResources", 
    contentType: "application/json; charset=utf-8", 
    dataType: "json", 
    data: '{resourceFileName:"mapedit",culture:"' + $("#lang-name").val() + '"}', 
    cache: true, 
    async: false, // to set local variable 
    success: function(data) { 
     localizations = data.d; 
    } 
}); 
+0

Funziona sicuramente, ma blocca il thread dell'interfaccia utente, vero? (Forse è accettabile, anche se non sembra necessario date le informazioni che abbiamo finora.) –

+0

Sì, blocca, ma ovviamente solo per la durata della richiesta. Non vedo nessun altro modo, dato quello che stai cercando. Sono andato giù per la stessa strada e ho seguito il percorso di sincronizzazione. – ScottE

Problemi correlati