2009-07-07 1 views
2

Ich habe ein Problem beim Zurückgeben von Daten an die Funktion, die ich zurückgeben möchte. Code unten:Wie gibt man Daten an die ursprüngliche Aufruferfunktion in Javascript zurück?

function ioServer(request_data, callback) 
{ 
    $.ajax({ 
     cache: false, 
     data: "request=" + request_data, 
     dataType: "json", 
     error: function(XMLHttpRequest, textStatus, errorThrown){}, 
     success: function(response_data, textStatus){ 
      callback(response_data); 
      }, 
     timeout: 5000, 
     type: "POST", 
     url: "/portal/index.php/async" 
    }); 
} 

function processRequest(command, item, properties) 
{ 
    var request = {}; 
    request.command = command; 
    request.item = item; 
    request.properties = properties; 
    var toServer = JSON.stringify(request); 
    var id = ioServer(toServer, processResponse); 
    return id; 
} 

function processResponse(fromServer) 
{ 
    if (fromServer.response == 1) 
    { 
     return fromServer.id; 
    } 
} 

Ich rufe dieses Stück Code auf, indem ich die processRequest Funktion in einer anderen Funktion aufruft. Senden der Anfrage und Abrufen der Antwort funktioniert gut. Allerdings muss ich einen Wert "ID" aus der Antwort zurück an die ProcessRequest-Funktion zurückgeben, so dass es wiederum diesen Wert an seinen Aufrufer zurückgeben kann. Soweit ich dem folgen kann, kehrt die Rückgabe in processResponse zu $ ​​.ajax zurück, aber ich brauche sie, um weiter zu processRequest zurückzukehren.

BTW Die if-Anweisung in processResponse bezieht sich auf einen Wert, der vom serverseitigen PHP-Skript festgelegt wurde, um festzustellen, ob die Anforderung zulässig war (wenn z. B. der Benutzer nicht angemeldet war, wäre fromServer.response 0). Es hat nichts mit den Erfolgs-/Fehlerroutinen des $ .ajax-Objekts zu tun.

Vielen Dank für die Hilfe.

@Jani: Danke für die Antwort, aber könnten Sie ein bisschen mehr klären? Die Funktion, wo ‚id‘ benötigt wird, hat den folgenden Code:

$(#tabs).tabs('add', '#tab-' + id, 'New tab'); 

Sie sagen, ich sollte versuchen, dieses Stück Code in der Process Funktion auszuführen? Weil ich das nicht beabsichtigte; Diese Funktion soll eine Allzwecklösung sein, um den Zustand serverseitig zu erhalten. Deshalb habe ich es vermieden, diesen Code dort anzubringen.

Antwort

3

Da Tony keine Kommentare zur Verfügung gestellt hat, lassen Sie mich Details hinzufügen, was er vorschlägt.

Wie Sie erfahren haben, wird die processRequest-Funktion beendet, sobald $ .ajax aufgerufen wird, weil $ .ajax asynchron ist. Wie würden Sie den Aufrufer von processRequest benachrichtigen, dass die Aufgabe erledigt ist?

Einfach, Sie fragen, dass der Aufrufer von ProcessRequest eine "Callback-Funktion" zu liefern. Die processRequest ruft diese Funktion auf, sobald sie die Ajax-Ausgabe erhalten hat. Im tony-Code ist dies das letzte Argument der processRequest-Funktion. schauen jetzt

So wird Ihre Telefonvorwahl wie

function tabMethod() 
{ 
    processRequest('command', 'item', 'properties', 
        function(id) 
        { 
        if(id == null) 
        { 
          alert('There is a problem!'); 
          return; 
        } 
        $('#tabs').tabs('add', '#tab-' + id, 'New tab'); 
        }); 


}; 
+0

Ja, danke für die ausdrückliche Klärung der Verwendung! –

+0

Und eine Abstimmung für die tolle Klärung ... –

3

Da dies eine asynchrone Anfrage ist, gibt es keinen solchen Wert direkt zurück und es ist nicht möglich.

Der Weg, dies zu erreichen, ist eine Methode zu haben, die alle Aktionen ausführt, die Sie für die abgerufenen Daten benötigen, anstatt zu versuchen, einen Rückgabewert zu haben, der nicht funktioniert.

5

Ich denke, vielleicht ist näher an, was Sie suchen ...

function ioServer(request_data, callback) 
{ 
    $.ajax({ 
     cache: false, 
     data: "request=" + request_data, 
     dataType: "json", 
     error: function(XMLHttpRequest, textStatus, errorThrown){}, 
     success: function(response_data, textStatus){ 
       processResponse(response_data, callback); 
       }, 
     timeout: 5000, 
     type: "POST", 
     url: "/portal/index.php/async" 
    }); 
} 

function processRequest(command, item, properties, callback) 
{ 
    var request = {}; 
    request.command = command; 
    request.item = item; 
    request.properties = properties; 
    var toServer = JSON.stringify(request); 
    ioServer(toServer, callback); 
} 

//internal callback to handle response code 
function processResponse(fromServer, callback) 
{ 
    if (fromServer.response == 1) 
    { 
     //call the callback with the id 
     callback(fromServer.id); 
    } 
    else 
    { 
     //You have to remember to call the callback no matter what 
     //or the caller won't know when it's complete 
     callback(null); //or some other "didn't get a valid response" value 
    } 
} 
+0

Erläuterung für Ihren Code-Vorschlag hinzugefügt und wie der aufrufende Code aussehen wird. Ich hoffe, es macht dir nichts aus. http://stackoverflow.com/questions/1094716/how-does-one-return-data-to-the-original-caller-function-in-javascript/1095251#1095251 – SolutionYogi

+0

was ist, wenn ich Antwort zurückgeben möchte processRequest von ioServer und wenn mehr als 1 Funktionen ioServer aufrufen, bin ich mir nicht sicher über Requestee Funktionsname ????? – dnxit

0

Statt Blockierung der Implementierung eines synchronen Aufruf wie jemand zu simulieren sonst vorher geschrieben, machen nur die AJAX nennen sich synchron und Update Ihr Erfolgswrapper:

Edit: Obwohl nützlich, das ist sorta gegen den Strich von "normalen" AJAX verwenden. Ich würde vorschlagen, stattdessen Ihren Ansatz zu ändern.

+1

Sie möchten keinen synchronen Aufruf durchführen, da dies den Browser einfrieren könnte, wenn die Ajax-Anfrage nicht schnell abgeschlossen werden konnte. – SolutionYogi

+0

@solutionyogi Hah, ya, ich war gerade dabei, einen Schnitt darüber zu machen, als du kommentiert hast. Leider habe ich dies in der Vergangenheit ohne Probleme mit dem Einfrieren des Browsers gemacht. Soweit ich weiß, wartet JavaScript/Blöcke und führt nichts aus. –

1

Awesome! Vielen Dank für die Hilfe, es funktioniert jetzt wie ein Zauber. Und ich habe gelernt, Callbacks besser zu nutzen.Hier ist der volle Funktionscode:

createTab('#tabs'); // I'm using JQuery UI to handle tabs  

function createTab(parent_element){ 
      var name = {}; 
      name.name = "New tab"; 
      var position = {}; 
      position.position = $(parent_element).tabs('length') + 1; 
      var properties = new Array(); 
      properties[0] = name; 
      properties[1] = position; 
      processRequest(1, 1, properties, 
         function(id) 
         { 
         if(id == null) 
         { 
           alert('There is a problem!'); 
           return; 
         } 
         $('#tabs').tabs('add', '#tab-' + id, 'New tab'); 
         }); 
     } 

function ioServer(request_data, callback) 
{ 
    $.ajax({ 
     cache: false, 
     data: "request=" + request_data, 
     dataType: "json", 
     error: function(XMLHttpRequest, textStatus, errorThrown){}, 
     success: function(response_data, textStatus){ 
       processResponse(response_data, callback); 
       }, 
     timeout: 5000, 
     type: "POST", 
     url: "/portal/index.php/async" 
    }); 
} 

function processRequest(command, item, properties, callback) 
{ 
    var request = {}; 
    request.command = command; 
    request.item = item; 
    request.properties = properties; 
    var toServer = JSON.stringify(request); 
    ioServer(toServer, callback); 
} 

//internal callback to handle response code 
function processResponse(fromServer, callback) 
{ 
    if (fromServer.response == 1) 
    { 
     //call the callback with the id 
     callback(fromServer.id); 
    } 
    else 
    { 
     //You have to remember to call the callback no matter what 
     //or the caller won't know when it's complete 
     callback(null); //or some other "didn't get a valid response" value 
    } 
} 

Und es fügt eine neue Registerkarte am Ende der Liste auf der Seite hinzu. Dies wird jetzt auch serverseitig mit PHP und MySQL gespeichert, so wie ich es wollte.

Danke nochmal!

Verwandte Themen