Promise.all() 当所有承诺都解决时永远不会触发
Promise.all() Never fires when all promises resolved
我有以下代码异步循环遍历 table 的列表,依次为每个 table 执行每个查询。我确实知道由于 console.log
的延迟输出,所有 dbTableQueryPromises
承诺都会解决,但 promise.all
永远不会触发。我现在 table 只有一个 users
。代码和输出如下。
const dropAllDatabaseTables = () => {
// tableRequiredList is an object that contains a list of SQL queries, among other things not important to the issue.
const errorList = [
'test'
];
return new Promise((allQueriesResolve, allQueriesReject) => {
const dbTableQueryPromises = tableRequiredList.map((databaseTable) => {
return new Promise((tableResolve, tableReject) => {
const dbQueries = databaseTable.table.dropTableQuery;
dbQueries.reduce((previousPromise, dbTableQuery) => {
return previousPromise.then(() => {
return new Promise((resolve, reject) => {
Logger.info(`Query (${databaseTable.name}): ${dbTableQuery}`);
dbConn.query(dbTableQuery, function(err, results, fields) {
if (err) {
Logger.error(`Exec error '${databaseTable.name}'. Error reported: ${err}`);
errorList.push({ err, dbTableQuery });
reject(err);
return null;
}
resolve({ results, fields });
});
});
}).catch((err) => {
Logger.error(`Exec error '${databaseTable.name}'. Error reported: ${err}`);
});
}, Promise.resolve()).then(() => {
Logger.info(`Table Drop Completed: ${databaseTable.name}`);
tableResolve(errorList);
}).catch((err) => {
Logger.error(`Exec loop error '${databaseTable.name}'. Error reported: ${err}`);
tableResolve(errorList);
});
});
});
console.log(1111, dbTableQueryPromises) // debug code
setTimeout(() => { // debug code
console.log(2222, dbTableQueryPromises) // debug code
}, 1000) // debug code
Promise.all(dbTableQueryPromises, (results) => {
console.log(3333, dbTableQueryPromises) // debug code
Logger.info(`All tables dropped.`);
allQueriesResolve(results);
});
});
};
输出:
1111 [ Promise { <pending> } ]
info: Query (users.js): DROP TABLE IF EXISTS `users`;
info: Table Drop Completed: users.js
2222 [ Promise { [ 'test' ] } ]
Promise.all
是基于 Promise 的,而不是基于回调的。它只接受一个参数:要等待的 Promises 数组。然后它 returns 一个 Promise,当该数组中的所有 Promise 都已解决时解决(或者,一旦其中一个 Promise 拒绝,它就会拒绝)。
在 Promise.all
上调用 .then
而不是尝试向其传递回调:
Promise.all(dbTableQueryPromises).then((results) => {
console.log(3333, dbTableQueryPromises) // debug code
Logger.info(`All tables dropped.`);
allQueriesResolve(results);
});
我有以下代码异步循环遍历 table 的列表,依次为每个 table 执行每个查询。我确实知道由于 console.log
的延迟输出,所有 dbTableQueryPromises
承诺都会解决,但 promise.all
永远不会触发。我现在 table 只有一个 users
。代码和输出如下。
const dropAllDatabaseTables = () => {
// tableRequiredList is an object that contains a list of SQL queries, among other things not important to the issue.
const errorList = [
'test'
];
return new Promise((allQueriesResolve, allQueriesReject) => {
const dbTableQueryPromises = tableRequiredList.map((databaseTable) => {
return new Promise((tableResolve, tableReject) => {
const dbQueries = databaseTable.table.dropTableQuery;
dbQueries.reduce((previousPromise, dbTableQuery) => {
return previousPromise.then(() => {
return new Promise((resolve, reject) => {
Logger.info(`Query (${databaseTable.name}): ${dbTableQuery}`);
dbConn.query(dbTableQuery, function(err, results, fields) {
if (err) {
Logger.error(`Exec error '${databaseTable.name}'. Error reported: ${err}`);
errorList.push({ err, dbTableQuery });
reject(err);
return null;
}
resolve({ results, fields });
});
});
}).catch((err) => {
Logger.error(`Exec error '${databaseTable.name}'. Error reported: ${err}`);
});
}, Promise.resolve()).then(() => {
Logger.info(`Table Drop Completed: ${databaseTable.name}`);
tableResolve(errorList);
}).catch((err) => {
Logger.error(`Exec loop error '${databaseTable.name}'. Error reported: ${err}`);
tableResolve(errorList);
});
});
});
console.log(1111, dbTableQueryPromises) // debug code
setTimeout(() => { // debug code
console.log(2222, dbTableQueryPromises) // debug code
}, 1000) // debug code
Promise.all(dbTableQueryPromises, (results) => {
console.log(3333, dbTableQueryPromises) // debug code
Logger.info(`All tables dropped.`);
allQueriesResolve(results);
});
});
};
输出:
1111 [ Promise { <pending> } ]
info: Query (users.js): DROP TABLE IF EXISTS `users`;
info: Table Drop Completed: users.js
2222 [ Promise { [ 'test' ] } ]
Promise.all
是基于 Promise 的,而不是基于回调的。它只接受一个参数:要等待的 Promises 数组。然后它 returns 一个 Promise,当该数组中的所有 Promise 都已解决时解决(或者,一旦其中一个 Promise 拒绝,它就会拒绝)。
在 Promise.all
上调用 .then
而不是尝试向其传递回调:
Promise.all(dbTableQueryPromises).then((results) => {
console.log(3333, dbTableQueryPromises) // debug code
Logger.info(`All tables dropped.`);
allQueriesResolve(results);
});