javascript - 等待 Promise.all 继续执行

标签 javascript promise

我想将产品插入数组,然后继续使用该数组。我没有使用 Promise 的经验。下面是我的代码。 这是我想返回数组的函数。

const findProduct = async function(request) {
  const products = [];

  await Promise.all(
    request.products.forEach(async product => {
      await db
        .get()
        .collection('products')
        .findOne({ _id: product.productId.toString() }, (err, result) => {
          if (err) throw new Error('exception!');
          products.push(result);
        });
    })
  )
    .then(() => {
      return products;
    })
    .catch(e => e);
};

产品始终是未定义的。

我应该返回 Promise.all 我将其保存到一个数组中,然后使用该数组吗?

这就是我计划使用数组的方式

const purchase = new Purchase(req.body);

const products = await findProduct(req.body);
purchase.products = [...products];

最佳答案

findProduct 函数的上下文中,如果您打算等待,则使用 async/await 语法没有多大意义使用 const products = wait findProduct(req.body);

findProduct 的结果

相反,您只想使用 Promise 来定义函数。

首先,db.collection.findOne() 使用异步事件的回调,要在 Promise 链中使用它,您必须将其包装在 Promise 中。可以像这样完成:

new Promise((resolve, reject) => {
  db
    .get()
    .collection('products')
    .findOne({ _id: product.productId.toString() }, (err, result) => { err ? reject(err) : resolve(result) })
});

这里 (err, 结果) => { err ? reject(err) :resolve(result) } 只是

的简洁形式
(err, result) => {
  if (err) {
    reject(err);
  } else {
    resolve(result);
  }
}

接下来,您必须将一个数组传递给 Promise.all()。由于您已经拥有数组 request.products,因此您可以将每个值转换(或映射)到其对应的 Promise 以获取其数据。这是使用 Array.prototype.map 完成的。以这种方式使用时,Promise.all() 将解析为与 request.products 顺序相同的产品数据对象数组。

将其混合到您的代码中,会产生:

const findProduct = function(request) {
  return Promise.all(
    request.products.map(product => {
      return new Promise((resolve, reject) => {
        db
          .get()
          .collection('products')
          .findOne({ _id: product.productId.toString() }, (err, result) => err ? reject(err) : resolve(result))
      });
    })
  );
};

请注意,我删除了 .then(()=>products) (因为由于上面的 promise ,Promise.all 将返回产品本身)和 .catch(e=>e ) (因为你不应该忽略这样的错误)。

通过这些更改,您现在可以像在问题中使用 findProduct 一样使用它。

<小时/>

更新:

似乎 MongoDB API 符合 Promise,这意味着我们可以删除 Promise 回调包装器并将其简化为:

const findProduct = function(request) {
  return Promise.all(
    request.products.map(product => {
      return db
        .get()
        .collection('products')
        .findOne({ _id: product.productId.toString() });
    })
  );
};

关于javascript - 等待 Promise.all 继续执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59499916/

相关文章:

javascript - JQuery 未定义响应

javascript - 为什么我的 Service Worker 总是在等待激活?

Javascript 替代 jquery html()

typescript - 我做错了 Promise...我在这里错过了什么?

javascript - 我怎样才能重写这些 JavaScript promise 而不那么复杂?

javascript - 将大文件存储在 chromecast 内存中

javascript - 如何加快 CKEditor 的速度

带有 Promise 和 if 语句的 Angular Auth Guard

JavaScript promise : how to deal with token expiry in API calls?

javascript - 如何将参数传递给链式 Promise 回调