【问题标题】:Pushing promises in an array the array remains null在数组中推送承诺,数组保持为空
【发布时间】:2021-12-26 13:23:55
【问题描述】:

我在 promises =[] 数组中推送承诺,但是当在承诺中传递承诺时。如果我的代码有任何问题,所有数组都保持为 null 并解决并发送 null 结果请回答

searchProductVariant: (start, end, combinations) => {
return new Promise((resolve,reject)=>
{
  var promises = [];
  console.log(start, "  ", end);
  for (let i = start; i < start + end; i++) {
    vv = combinations[i - start].product_variant_name.split("_");
    console.log("kk", vv);

    vv.forEach((v) => {
      sql = `SELECT id FROM ecommerce.variant_values as varval where varval.value like '${v}'`;
      pool.query(sql, [], (error, results, fields) => {
        if (error) {
          console.log("the errrror is", error);
        }
        if (results[0].id) {
          console.log("i is ", i);
          let temp = addProductVariantDetails(i, results[0].id);
          promises.push(temp
          );
        }
      });
    });
  }
  console.log(promises); //it prints null
  return Promise.all(promises)
    .then((resul) => {
      return resolve(resul);
    })
    .catch((err) => {
      return reject(err);
    });
})
}

【问题讨论】:

  • 这段代码应该做什么?此外,这看起来不像完整的代码。请发帖minimal reproducible example
  • 这是 addProductVariantDetails 函数返回一个承诺返回一个承诺的完整代码
  • 这个函数在哪里调用?可能的输入是什么?预期的输出是什么?
  • 预期的输出是在数据库中成功添加行时来自数据库的消息,或者如果出现错误则为错误消息。 addProductVariantDetails 在数据库中保存变体详细信息并返回一个承诺它。此函数多次调用,因此将其推送到数组中。在 promise.all 中传递该数组应该等到所有 promise 解决并传递结果
  • 这段代码有一些明显的问题,但是您是否考虑过为您的数据库寻找一个支持 promise/async/await 的客户端?

标签: node.js promise promise.all


【解决方案1】:

pool.query 收到回调,这是添加到 promises 数组中的唯一内容。我认为您可能只是想在任何query 回调返回之前运行Promise.all。您可能需要切换到基于 Promise 的 pool.query 版本(如果存在),或者您可以像这样编写自己的版本。

searchProductVariant: (start, end, combinations) => {
  // DELETE: Original Promise wrapper. Return Promise.all result directly.
  var queries = [];  // NEW: Track queries.
  var promises = [];
  console.log(start, "  ", end);
  for (let i = start; i < start + end; i++) {
    vv = combinations[i - start].product_variant_name.split("_");
    console.log("kk", vv);

    vv.forEach((v) => {
      sql = `SELECT id FROM ecommerce.variant_values as varval where varval.value like '${v}'`;
      // NEW: Wrap pool.query to create a promise that waits for the possible add
      // to the promises array, adding the separate promises array.
      queries.push(
        new Promise((resolve, _) => {
          pool.query(sql, [], (error, results, fields) => {
            resolve([error, results, fields]);
          })
        }).then([error, results, fields] => {
          if (error) {
            console.log("the error is", error);
          }
          if (results[0].id) {
            console.log("i is ", i);
            let temp = addProductVariantDetails(i, results[0].id);
            // Keep temp in an array so we only return valid results,
            // but also return it so the returned Promise surfaces
            // any rejection issued at any time.
            promises.push(temp);
            return temp;
          }
        }));
    });
  }
  console.log(promises);
  // Wait for the queries, then wait for the promise results.
  return Promise.all(queries).then(() => Promise.all(promises));
}

您还可以通过完全删除 promises 数组并在末尾简单地返回 Promise.all(queries) 来简化此代码;但是,您需要过滤掉来自任何导致错误或无 ID 结果的 queries 承诺的 undefined 结果,而且我对您的代码知之甚少,无法知道 undefined 是否可以适当过滤。 (您也不会检查 results.length &gt; 0,但您拥有它会导致 Promise 被拒绝。)

【讨论】:

  • "您还可以通过将 promises.push(temp) 替换为 return temp" 来简化此代码 - 这不仅仅是简化,实际上是更正。如果addProductVariantDetails 返回的temp 承诺之一在所有queries 完成之前拒绝,则当前编写的代码将导致未处理的承诺拒绝 错误(这可能会使进程崩溃) . (以及如果任何查询拒绝)。请按照您的建议解决此问题。
  • @Bergi 哦,我在删除外部 Promise 构造函数之前写了关于解决的那一点,但忘记删除描述。也就是说,除了pool.query 本身同步抛出之外,我看不到未处理的承诺拒绝来自哪里。如果addProductVariantDetails 拒绝或抛出,它将表现为整体返回值拒绝,因此没有任何事情未处理。
  • 问题在于,只有在第二个 Promise.all 运行后,拒绝才会表现为整体返回值 - 只有在所有查询都完成后才会发生。如果任何 temp 承诺在此之前拒绝,则它还没有设置 .then() 处理程序,并且将导致未处理的拒绝错误。
  • @Bergi 在这里,如果它能让你开心,我会return temp,但也会继续推送promises,因为OP 没有告诉我们undefined 是否是一个有效的承诺分辨率值。复制queriespromises 的效率有点低,但只有一点点,并且可以防止我的代码在功能上与 OP 不同。
猜你喜欢
  • 2020-11-18
  • 2019-06-13
  • 2019-07-28
  • 2014-08-30
  • 1970-01-01
  • 2022-08-18
  • 2019-12-13
  • 2019-11-07
  • 1970-01-01
相关资源
最近更新 更多