2011-08-25 27 views
5

tengo este código:obtener los datos de la función asíncrona

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 

y no funcionan como se esperaba (que no devuelve nada). Supongo que sucedió porque db.transaction funciona de forma asíncrona, pero estoy usando la devolución de llamada para devolver datos. ¿Alguien puede explicar por qué no funciona y cómo solucionarlo?

Respuesta

5

La forma habitual de hacer esto es para incluir su propio devolución de llamada, así:

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

entonces, no hay forma de poner esa matriz en una función asincrónica variable? – nukl

+0

@nukl: Puede asignar los valores a las variables en cualquier ámbito superior (por ejemplo, a variables globales), pero esto no lo ayuda. El punto importante cuando se utilizan devoluciones de llamada es * cuando * se accede a los datos. Si accede a la variable * antes de * la devolución de llamada se ejecutó (y se estableció el valor), obtiene datos incorrectos o no hay datos. Existen casos de uso perfectamente válidos para asignar la respuesta a otras variables, fuera de la devolución de llamada, pero debe tener en cuenta las implicaciones de realizar llamadas asíncronas. –

+0

@nukl, a menos que desee utilizar CoffeeScript (un lenguaje compilado en JavaScript): http://jashkenas.github.com/coffee-script/ –

0

no devuelve el resultado de cualquier acción asíncrono, en vez que escuchas por ello.

En su código returnData devuelve los datos, pero si no hace nada con el resultado, se descarta. En cambio, debe usar su propia devolución de llamada.

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; 
}); 
Cuestiones relacionadas