2017-10-04 4 views
0

J'essaie de comprendre comment obtenir plusieurs appels d'attente dos à dos dans l'ordre séquentiel. Voici ma configuration:Plusieurs types d'écritures séquentielles attendent de ne pas bloquer

  • tapuscrit
      2.5.2
    • transpiling à ES5
    • utilisant libs es2017 et dom dans TSconfig
  • Node.js 8.6
  • déployer dans un conteneur docker courir dans le minikube 0.22.2

Voici le code du problème. Il lance une requête sur postgresql en utilisant le paquet pg node. Je me suis basé sur l'exemple de code https://node-postgres.com/features/transactions#a-pooled-client-with-async-await.

import { Client, Pool } from 'pg'; 

// An existing client connection can be passed in so that the calling code 
// can manage a transaction. If none is provided, a new connection is 
// retrieved from the connection pool. 
async function query(
    connPool: Pool, 
    querystr: string, 
    params: (number | string)[], 
    client?: Client 
): Promise<any[]> { 
    let result; 
    let conn: Client = client; 
    if (conn) { 
    result = await conn.query(querystr, params); 
    } 
    else { 
    conn = await connPool.connect(); 
    result = await conn.query(querystr, params); 
    conn.release(); 
    } 
    return result.rows; 
} 

Et j'appelle la funtion requête() à partir d'un autre fichier, comme ceci:

const results = await query(myPool, 'SELECT * FROM my_table'); 
doOtherThing(results); 

Sur la base de tous les exemples de code source que je l'ai vu, je me attends à se comporter de cette façon:

  • fait appel à query()
  • conn = await connPool.connect(); ligne
  • blocs jusqu'à ce qu'une connexion est extrait de la piscine
  • ligne result = await conn.query(querystr, params); blocs jusqu'à ce que les résultats de la requête sont récupérés
  • renvoie les résultats en ligne return result.rows; au code d'appel
  • le code d'appel reçoit les enregistrements de la base de données
  • doOtherThing() est appelée

Cependant, il est l'exécution dans cet ordre:

  • appel fait à la requête()
  • ligne conn = await connPool.connect(); retourne immédiatement
  • le code d'appel reçoit undefined dans les résultats
  • doOtherThing() est appelée
  • ligne result = await conn.query(querystr, params); retourne immédiatement, nulle part
  • ligne return result.rows; résultats sont retournés nulle part

Tous des conseils sur ce que je fais mal? Suis-je complètement égaré sur la bonne façon d'utiliser async/wait?

+2

La mine fonctionne très bien. Comment créez-vous '' 'connPool'''? Quelle version du noeud utilisez-vous? A quoi sert votre '' '' target''' dans '' 'tsconfig.json'''? – Wainage

+0

@Wainage: Je crée le pool de connexion avec 'connPool = new Pool (settings)', où settings est un objet avec la configuration de connexion postgres. En utilisant le noeud 8.6. La cible dans tsconfig est es5. Le code query() ci-dessus est implémenté dans un paquet séparé que j'importe (que j'ai aussi écrit), donc il se trouve dans node_modules/du projet où j'appelle la fonction. – RobotNerd

+0

J'ai mis à jour l'exemple de code pour plus de clarté, ce qui illustre mieux ce qui se passe. J'ai une instruction 'doOtherThing (results);' qui se produit après l'appel à query(). J'ai écrit ceci en supposant que cette instruction ne serait pas appelée jusqu'à ce que toutes les fonctions asynchrones attendues dans la fonction query() aient résolu leurs promesses. – RobotNerd

Répondre

0

J'ai trouvé le problème. Le comportement attendu exposé dans la question est correct.

Entre l'instruction const results = await query(myPool, 'SELECT * FROM my_table'); et la fonction réelle était une autre fonction du même nom query(). Cette autre fonction a agi comme un passage à l'implémentation de la fonction query() que j'ai incluse dans la publication d'origine.Cette fonction au milieu n'a rien retourné, ce qui a provoqué le comportement inattendu.