2010-07-30 7 views
5

Considérez ce code (raccourci)De retour des valeurs de fonctions imbriquées 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 
      ); 
     } 
    ) 
} 

Comment pourrais-je retourner la valeur de secret pour la fonction principale? J'ai lu cette réponse Return value from nested function in Javascript

Et essayé

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; 
} 

Cependant, cela n'a pas fonctionné.

Merci!

Répondre

4

Essayez:

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

L'opération de base de données n'est-elle pas asynchrone? Je suis à peu près sûr que c'est le cas et que, par conséquent, la solution ici ne peut pas fonctionner. La fonction de rappel "success" est appelée lorsque la requête est terminée, tandis que la fonction externe retourne immédiatement après le démarrage de la requête *. – Pointy

+0

comment faire ce travail quand il est asynchrone? – Madhusudhan

+0

Avez-vous déjà répondu à ce problème «asynchrone»? – 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; 
} 

Cela va créer une fermeture sur la variable retval. Lorsque transaction est appelé, retval sera mis à jour. Essayez de promettre l'opération de base de données avant de renvoyer votre charge utile.

+6

Cela ne fonctionnera pas. La fonction de rappel de la requête est exécutée de manière asynchrone, tandis que le retour de 'getSecret()' aura lieu immédiatement après le début de la transaction *. – Pointy

0

De plus, vous pouvez utiliser la fonction reject() intégrée dans reject() en tant que gestionnaire d'erreur, en retournant l'objet de transaction chaque fois que la fonction renvoie undefined.

Declare promesse au sein de la fonction:

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

appeler ensuite la fonction.

//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) 
}) 

Espérons que ça aide.

Questions connexes