Promise.all () Никогда не срабатывает, когда все обещания разрешены - PullRequest
1 голос
/ 02 февраля 2020

У меня есть следующий код, который асинхронно просматривает список таблиц, последовательно выполняя каждый запрос для каждой таблицы. Я знаю, что все обещания dbTableQueryPromises разрешаются из-за задержанного вывода console.log, но promise.all никогда не срабатывает. У меня сейчас только один стол 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' ] } ]

1 Ответ

3 голосов
/ 02 февраля 2020

Promise.all основано на Promise, а не на обратном вызове. Он принимает только один параметр: массив Promises для ожидания. Затем он возвращает Обещание, которое разрешается, когда все Обещания в этом массиве разрешены (или отклоняется, как только одно из этих Обещаний отклоняется).

Вызов .then на Promise.all вместо попытки передать это обратный вызов:

Promise.all(dbTableQueryPromises).then((results) => {
  console.log(3333, dbTableQueryPromises) // debug code
  Logger.info(`All tables dropped.`);
  allQueriesResolve(results);
});
...