2011-08-25 30 views
5

ho questo codice:ottenere i dati di funzione asincrona

function getData(){ 
     db.transaction(function(tx){ 
      tx.executeSql('SELECT * from q', [], function(tx, result){ 
       var q = []; 
       for (var i=0; i < result.rows.length; i++) { 
        q.push(result.rows.item(i)); 
       }; 
       console.log(q.length); // 3 
       returnData(q); 
      }); 
     }); 
    } 

    function returnData(data){ 
     console.log(data.length); // 3 
     return data; 
    } 

    var q = getData(); // undefined 

e non funzionano come previsto (ma non restituisce nulla). Un presupposto che è accaduto, perché db.transaction funziona in modo asincrono, ma sto usando la funzione callback per restituire i dati. Qualcuno può spiegare perché non funziona e come risolverlo?

risposta

5

Il modo standard per farlo è quello di includere il proprio richiamata, in questo modo:

function getData(callback){ 
    db.transaction(function(tx){ 
     tx.executeSql('SELECT * from q', [], function(tx, result){ 
      var q = []; 
      for (var i=0; i < result.rows.length; i++) { 
       q.push(result.rows.item(i)); 
      }; 
      console.log(q.length); // 3 
      callback(returnData(q)); 
     }); 
    }); 
} 

function returnData(data){ 
    console.log(data.length); // 3 
    return data; 
} 

getData(function(q) { 
    /* do something with q */ 
}); 
+0

quindi, non c'è modo, per mettere quell'array in una variabile fuori dalla funzione asincrona? – nukl

+0

@nukl: è possibile assegnare i valori alle variabili in qualsiasi ambito superiore (ad esempio a variabili globali), ma ciò non è di aiuto. Il punto importante quando si usano le callback è * quando * si accede ai dati. Se si accede alla variabile * prima * la richiamata è stata eseguita (e il valore è stato impostato), si ottiene un errore o nessun dato. Esistono casi d'uso perfettamente validi per assegnare la risposta ad altre variabili, al di fuori del callback, ma è necessario essere consapevoli delle implicazioni di effettuare chiamate asincrone. –

+0

@nukl, a meno che non vogliate usare CoffeeScript (un linguaggio compilato da to-javascript): http://jashkenas.github.com/coffee-script/ –

0

Non restituire il risultato di qualsiasi azione asincrona, invece si ascolta per esso.

Nel tuo codice returnData restituisce i dati, ma non fai nulla con il risultato, è scartato. Invece, dovresti usare il tuo callback.

function getData(callback){ 
    db.transaction(function(tx){ 
     tx.executeSql('SELECT * from q', [], function(tx, result){ 
      var q = []; 
      for (var i=0; i < result.rows.length; i++) { 
       q.push(result.rows.item(i)); 
      }; 
      console.log(q.length); // 3 
      callback(q); 
     }); 
    }); 
} 

var q; 
getData(function(data) { 
    console.log(data.length); // 3 
    console.log(data); 
    doStuffWith(data); 
    q = data; 
}); 
Problemi correlati