2011-10-15 21 views
20

Ho la seguente funzione jQuery. Sto cercando di restituire il valore GUID mostrato qui nel alert(); L'avviso funziona correttamente e il valore è popolato, tuttavia non riesco a assegnarlo a una variabile e restituire il suo valore.Valore restituito asincrono JavaScript/assegnazione con jQuery

In definitiva, ho bisogno di accedere al valore GUID in altre funzioni, ecc. Tutto ciò che ho provato viene visualizzato solo come undefined.

mi piacerebbe fare qualcosa di simile:

function trackPage(){ 
    var elqTracker = new jQuery.elq(459); 
    elqTracker.pageTrack({ 
     success: function() { 
      elqTracker.getGUID(function(guid) { 
       alert(guid); 
       var returnValue = guid; 
      }); 
     } 
    }); 
    return returnValue; 
} 

var someGuid = trackPage(); 
+2

è 'getGUID' una chiamata asincrona? – Anurag

+0

non sono sicuro .. È una chiamata plugin da altri JS (non una chiamata che posso modificare) .. Posso avvisare il valore .. e persino assegnarlo a una nuova variabile .. Posso solo sembrare ottenere quel valore al di fuori del funzione – patrick

+0

Suona sicuramente asincrono, in tal caso. –

risposta

47

Così, questa domanda è stato chiesto un milione di volte, e sono sicuro che tutti (me compreso) tried this once.

È solo la natura di una chiamata asincrona, non è possibile utilizzare i risultati come valore return. Ecco perché ti hanno passato in una funzione che ottiene il risultato della chiamata, non possono neanche return! Si noti inoltre che la chiamata alla funzione elqTracker.pageTrack() restituisce IMMEDIATAMENTE, pertanto returnValue è semplicemente undefined.

La maggior parte delle persone (vedere la risposta di dfsq) risolve questo problema introducendo una funzione di callback come parametro. Questo metodo è provato e vero – tuttavia jQuery ha $.Deferred. Questo ti permette di fare la propria logica asincrona restituire un promise che sarà poi possibile allegare qualsiasi numero di callback a:

function trackPage(){ 
    var elqTracker = new jQuery.elq(459), 
     dfd = $.Deferred(); 

    elqTracker.pageTrack({ 
     success: function() { 
      elqTracker.getGUID(function(guid) { 
       dfd.resolve(guid); 
      }); 
     } 
    }); 

    return dfd.promise(); 
} 

// example use: 
trackPage().done(function(guid) { 
    alert("Got GUID:" + guid); 
}); 

Notate ora che il vostro trackPage() restituisce un oggetto che è possibile allegare a callback? Non è necessario allegarli immediatamente.

var pageHit = trackPage().done(function(guid) { 
    alert("Page Hit GUID:" +guid); 
}); 

$("button").click(function() { 
    pageHit.done(function(guid) { 
     alert("Clicked on Page GUID:" + guid); 
    }); 
}); 

Inoltre, il modulo jQuery AJAX restituisce sempre promesse e, in modo l'interfaccia per tutte le tue cose AJAX dovrebbe essere molto simile se si fanno le proprie promesse di ritorno logica.


Come nota a margine: Vorrei far notare che il vostro var returnValue era dalla parte del torto "scope" in ogni caso. Doveva essere dichiarato nell'ambito esterno della funzione trackPage. Anche con questa correzione, il concetto continua a non funzionare.

13

visto che hai asincrono chiamare il modo in cui si sta tentando di scrivere codice non è andare a lavorare (perché per il momento di return returnValue; nel ritorno trackCode il valore non è ancora definito). Invece si dovrebbe passare richiamata in trackPage:

function trackPage(callback) { 
    var elqTracker = new jQuery.elq(459); 
    elqTracker.pageTrack({ 
     success: function() { 
      elqTracker.getGUID(function(guid) { 
       alert(guid); 
       // Instead of this: var returnValue = guid; 
       // You should use your callback function 
       callback(guid); 
      }); 
     } 
    }); 
    return returnValue; 
} 

trackCode(function(guid) { 
    // perform some actions with guid 
});