skip to Main Content

I’m working on a script to seed my database but am having issues with my node-pg connection being terminated before my rebuild function is finished.

const rebuildDB = async () => {
  try {
    client.connect();
    await dropTables();
    await createTables();
    await Promise.all(employees.map(createEmployee), customers.map(createCustomer));
  } catch (err) {
    console.log(err);
  } finally {
    client.end();
  }
};

rebuildDB();

When I remove the finally block everything runs correctly. If i leave it, the createEmployee function will execute but the connection will be terminated before createCustomer() is able to execute.

Any suggestions?

2

Answers


  1. You can concat your two promises arrays in order to have the one expected iterable argument

    await Promise.all(
      employees.map(createEmployee)
        .concat(
          customers.map(createCustomer)
        )
    );
    

    This is equivalent in terms of result with the spread operator given in other answers. However if your arrays are very large (and I assume they could be if they are all the entries from a db) the spread operator could throw a Maximum call stack size exceeded error. Concat is more efficient on large arrays, especially if you only have two arrays to merge.

    Read more about this on https://www.educative.io/answers/spread-operator-vs-arrayprototypeconcat-in-javascript

    Login or Signup to reply.
  2. Reposting my comment as a proper answer (and adding to it):

    There are two issues. The main one, which you asked about, is that you’re calling Promise.all incorrectly. It accepts only a single argument, not multiple arguments, so it’s ignoring the promises from the second argument entirely. You want to pass in a single iterable (probably an array in this case).

    The other problem is that you don’t want client.connect() inside the try, since you don’t want to call client.end() if client.connect() throws.

    So:

    const rebuildDB = async () => {
        // This shouldn't be *inside* the `try`, since you don't want to call
        // `client.end()` if this fails
        client.connect();  // <=== Does this need an await? It doesn't have one in your question...
        try {
            await dropTables();
            await createTables();
            // Pass a single array to `Promise.all`
            await Promise.all([...employees.map(createEmployee), ...customers.map(createCustomer)]);
        } catch (err) {
            console.log(err);
        } finally {
            client.end();
        }
    };
    
    rebuildDB();
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search