1
votes

Comment puis-je synchroniser la fonction tx.executeSql () avec async / await?

Comment puis-je faire de tx.executeSql (SQL, [], (tx, results) une fonction de synchronisation avec sync / await?

Je veux en faire quelques-unes comme ceci: p>

tx.executesql est asynchrone donc mon closeDB () ( closeDatabase () ) ne fonctionne pas car la transaction est en cours.


C:\Users\josen\React-Projects\Ges\src\Screen\Login.js:22 COMIENZA insertarDatos
C:\Users\josen\React-Projects\Ges\src\Screen\Login.js:88 Comienza Transaction
C:\Users\josen\React-Projects\Ges\src\Screen\Login.js:88 antes de excute i es: 0
C:\Users\josen\React-Projects\Ges\src\Screen\Login.js:88 antes de excute i es: 1
C:\Users\josen\React-Projects\Ges\src\Screen\Login.js:88 antes de excute i es: 2
C:\Users\josen\React-Projects\Ges\src\Screen\Login.js:88 antes de excute i es: 3
C:\Users\josen\React-Projects\Ges\src\Screen\Login.js:90 termina transaccion
C:\Users\josen\React-Projects\Ges\src\Screen\Login.js:112 TERMINA insertarDatos
C:\Users\josen\React-Projects\Ges\src\Screen\Login.js:128 Cerrando database ...
C:\Users\josen\React-Projects\Ges\src\Screen\DrawerScreens\index.js:7 cannot close: transaction is in progress
C:\Users\josen\React-Projects\Ges\src\Screen\Login.js:91 dentro de executesql i es: 0
C:\Users\josen\React-Projects\Ges\src\Screen\Login.js:93 ¡Datos insertados en BD!
C:\Users\josen\React-Projects\Ges\src\Screen\Login.js:91 dentro de executesql i es: 1
C:\Users\josen\React-Projects\Ges\src\Screen\Login.js:93 ¡Datos insertados en BD!
C:\Users\josen\React-Projects\Ges\src\Screen\Login.js:91 dentro de executesql i es: 2
C:\Users\josen\React-Projects\Ges\src\Screen\Login.js:93 ¡Datos insertados en BD!
C:\Users\josen\React-Projects\Ges\src\Screen\Login.js:91 dentro de executesql i es: 3
C:\Users\josen\React-Projects\Ges\src\Screen\Login.js:93 ¡Datos insertados en BD!

mais cela ne fonctionne pas.

(voir les sorties)

Voici l'avertissement que j'ai reçu à la fin de la sortie: p>

 insertarDatos = async () =>{
    console.log('COMIENZA insertarDatos');
     await db.transaction((tx) => {
       console.log('Comienza Transaction');
        for(let i in this.state.dataUsuarios){
          const sql = `INSERT INTO usuarios VALUES (
            '${this.state.dataUsuarios[i].id}', 
            '${this.state.dataUsuarios[i].nombre}',
            '${this.state.dataUsuarios[i].usuario}',
            '${this.state.dataUsuarios[i].password}',
            '${this.state.dataUsuarios[i].grupo}',
            '${this.state.dataUsuarios[i].faenas}'
          )`;
          console.log('antes de excute i es: ' + i);
          tx.executeSql(sql, [], (tx, results) => {
           console.log('dentro de executesql i es: ' + i);
            if(results.rowsAffected > 0){
              console.log('¡Datos insertados en BD!');
            }else{
              console.log('¡No se puedieron insertar datos en la BD!');
            }(error) => {
            console.log(error.message);
            }
          });
        }
        console.log('termina transaccion');
    });
    
    console.log('TERMINA insertarDatos');

  }
async componentDidMount() {


    console.log('*COMIENZA componentDidMount');
    await this.consultarBD();
    await this.openBD();

    console.log('DataUsuarios es: ' + this.state.dataUsuarios);
    await this.insertarDatos();
    await this.closeDatabase();

    console.log('*TERMINA componentDidMount');

  }
C:\...name of proyect\node_modules\react-native\Libraries\Components\ScrollView\InternalScrollViewType.js:46 Possible Unhandled Promise Rejection (id: 0):
TypeError: error is not a function
TypeError: error is not a function
    at SQLitePlugin.close (blob:http://localhost:8081/7a5bb020-64e9-41f5-a654-e50e6b9f5827:93749:9)
    at _callee4$ (blob:http://localhost:8081/7a5bb020-64e9-41f5-a654-e50e6b9f5827:92942:54)
    at tryCatch (blob:http://localhost:8081/7a5bb020-64e9-41f5-a654-e50e6b9f5827:23006:19)
.
.
.
.

Sorties:

await tx.executeSql(sql, [], (tx, results)


0 commentaires

3 Réponses :


3
votes

Essayez de l'implémenter comme ceci, en l'enveloppant dans une promesse, vous devriez pouvoir appeler cette fonction avec un await

await asyncForEach(userlist, async (user, index) => {
     // do something with user and index

     // you can use await here
})

Maintenant, si cela ne fonctionne pas ' t fonctionne, cela peut être un problème avec votre forin . Si tel est le cas, il peut être utile de consulter ce message . Il a une implémentation native d'un async foreach, qui pourrait être implémenté comme suit:

  insertarDatos = () => {
    return new Promise((resolve, reject) => {
      db.transaction((tx) => {
        try {
          /* Successful transaction */
          /* Make sure to call resolve when the transaction has finished
          */
          resolve()
        } catch (error) {
          /* Failed transaction */
          // if you reject any eventual errors, you can catch them when calling the function insertarDatos

          reject(error)
        }
      });
    })
  }


1 commentaires

J'aime cette réponse. Vous donne un contrôle total. Et c'est simple



4
votes

La méthode async / wait pour rendre executeSql():

async function example() {
  let db = await SQLite.openDatabase(
    database_name,
    database_version,
    database_displayname,
    database_size
  );

  await db.transaction(async tx => {
     var [tx, results] = await tx.executeSql("SELECT * from TableName;");
     var row = results.rows.item(0); //get the first row assumed existed.
  });

  await db.close();
}


2 commentaires

C'est une réponse concise mais je vois que vous avez dû utiliser deux déclarations var à la place, let ou const. J'ai essayé de changer cela mais Typescript s'est plaint à ce sujet. Je vois que vous avez utilisé let plus haut. Il est vraiment difficile de faire fonctionner async / await avec sqLite et de le comprendre. Surtout la raison du tableau [tx, results]. Je ne peux pas comprendre la raison pour laquelle tx apparaît là-bas.


@mwarren, tx est là parce que executeSql est une méthode asynchrone, peut-être que quelque part, vous avez encore besoin du tx pour exécuter un autre SQL.



0
votes
async getSqlitedata(): {
   const data = await dbconn.executeSql("SELECT * from TableName;",[]);
   if (data.rows.lenth >0) {
       console.log(data.rows);
   }
}
it will return a object {rows: {…}, rowsAffected: 0, insertId: undefined}

0 commentaires