Reputation: 1672
Working with Node and mssql to pull queries for five different databases to de-dupe against each other and merge into a more unified schema.
My process follows this algorithm:
create a shared pool by calling this function:
const getPoolConnection = async () => {
try {
let pool = await mssql.connect(`mssql://${username}:${password}@${server}/`);
return pool;
} catch (err) {
console.error(err);
}
};
This function creates the pool and returns it to the calling function. username
, password
, and server
are imported and scoped to this file.
Then we query each database and assign the result to a property on an object. This is accomplished via a forEach
loop:
lists.forEach(list => {
fullData[list] = db.queryDatabase(pool, customers[list].query).catch(err => console.error(err));
})
which calls this function:
const queryDatabase = async (pool, query) => {
try {
let result = await pool.request().query(query);
// console.log(result);
return result.recordset, pool;
} catch (err) {
console.error(err);
}
};
now in order to keep post-processing from occuring before all database calls return data, I've wrapped the entire set of calls in a Promise.all()
call in the main index.js
file. This is the calling funciton:
const { customers } = require('./query');
const util = require('./util');
const db = require('./db');
fullData = {};
(async () => {
let pool = await db.getPoolConnection();
let lists = Object.keys(customers);
Promise.all(
lists.forEach(list => {
fullData[list] = db.queryDatabase(pool, customers[list].query).catch(err => console.error(err));
})
)
.then(results, pool => {
console.dir(results);
db.closePoolConnection(pool);
})
.catch(err => console.error(err));
})();
What I don't understand is this error that occurs when attempting to debug the application:
(node:18908) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'Symbol(Symbol.iterator)' of undefined warning.js:18 at Function.all () at c:\Users\rutherfordc\Documents\GitHub\migration-plus\index.js:10:11 at at process._tickCallback (internal/process/next_tick.js:188:7) (node:18908) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1) warning.js:18 (node:18908) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code. warning.js:18 (node:18908) UnhandledPromiseRejectionWarning: ReferenceError: results is not defined warning.js:18 at c:\Users\rutherfordc\Documents\GitHub\migration-plus\index.js:15:11 at at process._tickCallback (internal/process/next_tick.js:188:7) (node:18908) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 2)
Upvotes: 0
Views: 1045
Reputation: 10009
Promise.all() needs an array. So you could do something like this:
fullData = [];
(async () => {
let pool = await db.getPoolConnection();
let lists = Object.keys(customers);
lists.forEach(list => {
fullData.push(db.queryDatabase(pool, customers[list].query).catch(err => console.error(err));
}));
Promise.all(fullData)
.then((results, pool) => {
console.dir(results);
db.closePoolConnection(pool);
})
.catch(err => console.error(err));
})();
Update:
Also as J. Pichardo suggested in his answer, in case of multiple parameters, the parameters should be enclosed in parentheses.
Documentation
Upvotes: 1
Reputation: 3115
The error is non-logical but syntactical, the following lines in the main function
.then(results, pool => {
console.dir(results);
db.closePoolConnection(pool);
})
The arguments of the arrow function should be surrounded by parentheses, like:
.then((results, pool) => {
console.dir(results);
db.closePoolConnection(pool);
})
ReferenceError: results is not defined
So, the then
is looking for a results
variable and since it is an async
function when it crashes it will be a UnhandledPromiseRejection
.
As the other answer says Promise.all
receives either multiple promises or an array of promises, so you could do something like:
var fullData = lists.map(list => db.queryDatabase(pool, customers[list].query).catch(err => console.error(err)));
Promise.all(fullData).then(...)
Upvotes: 1