【问题标题】:Promise.all() Never fires when all promises resolvedPromise.all() 当所有的 Promise 都解决时永远不会触发
【发布时间】:2020-02-02 01:36:06
【问题描述】:

我有以下代码异步循环遍历表列表,按顺序执行每个表的每个查询。我确实知道所有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' ] } ]

【问题讨论】:

  • 这是非常复杂的代码,因为它混合了承诺和普通回调。承诺在主要代码使用之外的所有异步函数。然后,只使用异步函数编写控制流,这些函数返回没有普通回调的承诺。然后,当然,您也可以重用 promisified 函数。但是,在您的情况下,您可能首先可以使用内置的 Promise 接口连接到您的数据库。
  • @jfriend00 我完全同意你的看法。代码将被重构。它现在只是用于原型设计。
  • 有点意思是,你甚至不应该在同一个控制流中混合使用 Promise 和普通的回调,即使是原型设计也是如此。在这种情况下,你的数据库有一个内置的 Promise 接口,如果你使用正确的数据库版本,你就可以使用它。

标签: javascript promise resolve


【解决方案1】:

Promise.all 是基于 Promise 的,而不是基于回调的。它只接受一个参数:要等待的 Promises 数组。然后它返回一个 Promise,当该数组中的所有 Promise 都已解决(或者,一旦其中一个 Promise 拒绝,它就会拒绝)。

Promise.all 上调用.then 而不是尝试向其传递回调:

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

【讨论】:

  • 啊,真不敢相信我错过了。谢谢,就是这个原因。一旦允许,我会将您的答案标记为答案。
猜你喜欢
  • 2018-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-13
  • 2020-06-23
  • 2018-02-06
  • 1970-01-01
  • 2017-03-18
相关资源
最近更新 更多