Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/368.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 所有的承诺都解决了,就永远不会开火_Javascript_Promise_Resolve - Fatal编程技术网

Javascript 所有的承诺都解决了,就永远不会开火

Javascript 所有的承诺都解决了,就永远不会开火,javascript,promise,resolve,Javascript,Promise,Resolve,我有下面的代码,它异步循环遍历表列表,顺序执行每个表的每个查询。我确实知道,由于console.log的输出延迟,所有dbTableQueryPromises承诺都得到了解决,但promise.all从未触发。我现在只有一张桌子。代码和输出如下 const dropAllDatabaseTables = () => { // tableRequiredList is an object that contains a list of SQL queries, among other t

我有下面的代码,它异步循环遍历表列表,顺序执行每个表的每个查询。我确实知道,由于console.log的输出延迟,所有dbTableQueryPromises承诺都得到了解决,但promise.all从未触发。我现在只有一张桌子。代码和输出如下

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.all(dbTableQueryPromises).then((results) => {
  console.log(3333, dbTableQueryPromises) // debug code
  Logger.info(`All tables dropped.`);
  allQueriesResolve(results);
});
一切都是基于承诺的,而不是基于回调的。它只接受一个参数:要等待的承诺数组。然后,它返回一个承诺,该承诺在该数组中的所有承诺都已解决时解决,或者在其中一个承诺被拒绝时立即拒绝

调用。然后调用Promise.all,而不是尝试向其传递回调:

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

啊,真不敢相信我错过了。谢谢,这就是原因。我会把你的答案记下来,让我来回答。啊,真不敢相信我错过了。谢谢,这就是原因。我会将你的答案标记为答案,这是一个非常复杂的代码,因为它是承诺和简单的回调的混合体。Promisify主代码使用之外的所有异步函数。然后,只使用异步函数编写您的控制流,这些函数返回承诺,并且没有明显的回调。当然,您还可以重用promisified函数。但是,在您的情况下,您可以首先使用数据库的内置promise接口。@jfriend00我完全同意您的看法。代码将被重构。这只是为了现在的原型设计,重点是你们甚至不应该在同一个控制流中混合承诺和简单的回调,即使是原型设计。在本例中,您的数据库有一个内置的promise接口,如果您使用正确版本的数据库,您就可以使用它。这是一个非常复杂的代码,因为它是promises和普通回调的混合体。Promisify主代码使用之外的所有异步函数。然后,只使用异步函数编写您的控制流,这些函数返回承诺,并且没有明显的回调。当然,您还可以重用promisified函数。但是,在您的情况下,您可以首先使用数据库的内置promise接口。@jfriend00我完全同意您的看法。代码将被重构。这只是为了现在的原型设计,重点是你们甚至不应该在同一个控制流中混合承诺和简单的回调,即使是原型设计。在本例中,您的数据库具有一个内置的promise接口,如果您使用正确版本的数据库,就可以使用该接口。