Ich habe mich gefragt, ob es eine Lösung gibt, um die Synchronisierung in JavaScript-Code durchzuführen. Zum Beispiel habe ich den folgenden Fall: Ich versuche, einige Antwortwerte von AJAX-Aufrufen zwischenzuspeichern. Das Problem ist, dass es möglich ist, mehrere Aufrufe gleichzeitig auszuführen, was zu einer Race Condition im Code führt. Daher bin ich sehr neugierig, eine Lösung dafür zu finden? Hat jemand eine Idee, die zu tun?
Antworten
Zu viele Anzeigen?Ich kann eine mögliche Lösung anbieten, aber ohne den Code zu sehen ... nicht ganz sicher, was Sie tun, aber es gibt keinen Grund, warum Sie dies nicht tun könnte.
Grundlegende Code in jQuery : (nicht getestet und abgekürzt ... aber ich habe Dinge ähnlich gemacht)
var needAllThese = {};
$(function(){
$.ajax("POST","/somepage.aspx",function(data) {
needAllThese.A = "VALUE";
});
$.ajax("POST","/somepage2.aspx",function(data) {
needAllThese.B = "VALUE";
});
$.ajax("POST","/somepage3.aspx",function(data) {
needAllThese.C = "VALUE";
});
startWatching();
});
function startWatching() {
if (!haveEverythingNeeded()) {
setTimeout(startWatching,100);
return;
}
everythingIsLoaded();
}
function haveEverythingNeeded() {
return needAllThese.A && needAllThese.B && needAllThese.C;
}
function everythingIsLoaded() {
alert("Everything is loaded!");
}
EDIT: (bezüglich Ihres Kommentars)
Sie sind für Rückrufe suchen, die gleiche Art und Weise jQuery würde es tun.
var cache = {};
function getSomeValue(key, callback) {
if (cache[key]) callback( cache[key] );
$.post( "url", function(data) {
setSomeValue(key,data);
callback( cache[key] );
});
}
function setSomeValue(key,val) {
cache[key] = val;
}
$(function(){
// not sure you would need this, given the code above
for ( var i = 0; i < some_length; ++i) {
$.post( "url", function(data){
setSomeValue("somekey",data);
});
}
getSomeValue("somekey",function(val){
$("#element").txt( val );
};
});
Javascript ist von Natur aus single-threaded, zumindest in der normalen Browserumgebung. Es wird nie zwei gleichzeitige Ausführungen von Skripten geben, die auf dasselbe Dokument zugreifen. (Die neuen Javascript-Worker-Threads könnten hier eine Ausnahme sein, aber sie sind nicht dazu gedacht, überhaupt auf Dokumente zuzugreifen, sondern nur, um per Message Passing zu kommunizieren).
Ich habe eine Lösung für mein Problem gefunden. Ich muss sagen, es ist nicht so perfekt, wie ich gesucht habe, aber so weit es funktioniert und ich denke, dass mehr als vorübergehend zu umgehen.
$.post( "url1", function( data)
{
// do some computation on data and then
setSomeValue( data);
});
var setSomeValue = ( function()
{
var cache = {};
return function( data)
{
if ( cache[data] == "updating")
{
setTimeout( function(){ setSomeValue( data);}, 100);
return;
}
if ( !cache[date])
{
cache[date] = updating;
$.post( "url2", function( another_data)
{
//make heavy computation on another_data
cache[data] = value;
// update the UI with value
});
}
else
{
//update the UI using cached value
}
}
})();
Ja können Sie Ihre xmlHttpRequests synchron machen, in nicht-IE setzen die Asynchron-Option bei der Methode "open" in IE-Browsern auf false setzen das Gleiche tun mit dem Parameter bAsync.
Vielleicht sollten Sie Ihre Anfragen irgendwie verketten. Erstellen Sie einen Warteschlangenstapel und senden Sie die Anfragen nach und nach ab.
Zunächst ist es wichtig zu wissen, dass alle aktuellen JS-Implementierungen single-threaded sind, daher diskutieren wir nicht über Race-Bedingungen und Synchronisierung in dem Kontext, in dem sie normalerweise verwendet werden.
Als Randbemerkung, Browser sind jetzt die Einführung von Worker-Threads, die Gleichzeitigkeit in JS ermöglichen wird, aber für jetzt ist dies nicht der Fall.
Wie auch immer, Sie haben immer noch Probleme mit den Daten, die Sie von asynchronen Aufrufen zurückerwarten, und Sie haben keine Garantie für die Reihenfolge, in der Sie die Daten erhalten werden.
JS gibt Ihnen eine sehr schöne Lösung für dieses Problem mit Rückrufe. Für jedes asynchrone Ereignis, das Sie senden werden, fügen Sie eine geeignete Callback-Funktion hinzu, die das Ereignis ordnungsgemäß verarbeitet. Synchronisierung in dem Sinne, wie Sie es meinen, dort stattfinden sollte.
- See previous answers
- Weitere Antworten anzeigen