2010-07-30 20 views
5

Considere este código (abreviado)Devolución de valores de funciones anidadas en Javascript

function getSecret() { 
    db.transaction(
     function (transaction) { 
      transaction.executeSql(
       'SELECT * FROM table LIMIT 1;', 
       null, 
       function(transaction, result) { 
        var row = result.rows.item(0); 
        var secret = row.secret; 
        return secret; 
       }, errorHandler 
      ); 
     } 
    ) 
} 

¿Cómo voy a devolver el valor de secreto para la función principal? He leído esta respuesta Return value from nested function in Javascript

y probado este

function getSecret() { 
    db.transaction(
     function doSql(transaction) { 
      transaction.executeSql(
       'SELECT * FROM table LIMIT 1;', 
       null, 
       function(transaction, result) { 
        var row = result.rows.item(0); 
        var secret = row.secret; 
        return secret; 
       }, errorHandler 
      ); 
     } 
    ) 
    return doSql; 
} 

Sin embargo, esto no funcionó.

Gracias!

Respuesta

4

Probar:

function getSecret() { 
    var secret = ''; 

    db.transaction(
     function (transaction) { 
      transaction.executeSql(
       'SELECT * FROM table LIMIT 1;', 
       null, 
       function(transaction, result) { 
        var row = result.rows.item(0); 
        secret = row.secret; 
       }, errorHandler 
      ); 
     } 
    ) 

    return secret; 
} 
+12

¿La operación de la base de datos no es asincrónica? Estoy bastante seguro de que así es, y que, por lo tanto, la solución aquí no puede funcionar. La función de devolución de llamada de "éxito" se llama cuando la consulta finaliza, mientras que la función externa regresa inmediatamente después de que la consulta se * inició *. – Pointy

+0

cómo hacer que esto funcione cuando es asincrónico? – Madhusudhan

+0

¿Alguna vez se ha respondido a este problema 'asincrónico'? – Black

1
function getSecret() { 
    var retval = undefined; // or a reasonable default 
    db.transaction(
     function doSql(transaction) { 
      transaction.executeSql(
       'SELECT * FROM table LIMIT 1;', 
       null, 
       function(transaction, result) { 
        var row = result.rows.item(0); 
        var secret = row.secret; 
        retval = secret; 
       }, errorHandler 
      ); 
     } 
    ) 
    return retval; 
} 

Esto creará un cierre sobre la variable retval. Cuando se llama transaction, se actualizará retval.

+6

Esto no funcionará. La función de devolución de llamada de la consulta se ejecuta de forma asíncrona, mientras que el retorno de 'getSecret()' se producirá inmediatamente después de que la transacción * se haya iniciado *. – Pointy

0

Intente promisificar la operación de la base de datos antes de devolver su carga útil.

Además, puede usar el rechazo incorporado de promise() como manejador de errores, devolviendo el objeto de transacción cada vez que la función devuelve indefinido.

promesa Declarar dentro de la función:

function getSecret() { 
    var secret = ''; 
    return new Promise(function(resolve, reject) { 
     db.transaction(
      function(transaction) { 
       transaction.executeSql(
        'SELECT * FROM table LIMIT 1;', 
        null, 
        function(transaction, result) { 
         if (typeof(result) === 'undefined') { 
          var row = result.rows.item(0); 
          secret = row.secret; 
          resolve(secret) 
         }, 
         else { 
          reject(transaction) 
         } 
        } 
       ); 
      } 
     ) 
    }) 
} 

Luego llama a la función.

//If function resolves, log the secret. 
//if function rejects, log the transaction 
getSecret().then(function(secret) { 
    console.log(secret); 
}) 
.catch(function(err) { 
    console.log('Error in db.transaction ' + err) 
}) 

Espero que ayude.

Cuestiones relacionadas