Search code examples
node.jstypescriptasync-awaitecmascript-5

Typescript multiple sequential awaits not blocking


I'm trying to figure out how to get multiple back-to-back await calls to occur in sequential order. Here's my setup:

  • typescript 2.5.2
    • transpiling to es5
    • using libs es2017 and dom in tsconfig
  • node.js 8.6
  • deploying to a docker container running in minikube 0.22.2

Here's the problem code. It's running a query against postgresql using the node pg package. I based it off of the example 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;
}

And I'm calling the query() funtion from another file, like so:

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

Based on every source code example I've seen, I expect it to behave this way:

  • call made to query()
  • line conn = await connPool.connect(); blocks until a connection is retrieved from the pool
  • line result = await conn.query(querystr, params); blocks until the results of the query are retrieved
  • line return result.rows; returns results to the calling code
  • the calling code receives the records from the database
  • doOtherThing() is called

However, it's executing in this order:

  • call made to query()
  • line conn = await connPool.connect(); returns immediately
  • the calling code receives undefined in results
  • doOtherThing() is called
  • line result = await conn.query(querystr, params); returns immediately, to nowhere
  • line return result.rows; results are returned to nowhere

Any guidance on what I'm doing wrong? Am I completely misguided on the right way to use async/await?


Solution

  • I found the problem. The expected behavior laid out in the question is correct.

    In between the statement const results = await query(myPool, 'SELECT * FROM my_table'); and the actual function was another function with the same name query(). This other function acted as a pass-through to the implementation of the query() function that I included in the original post. This function in the middle didn't return anything, which caused the unexpected behavior.