首页 > 解决方案 > 循环promise中的每个项目并过滤结果

问题描述

你好我有这个数组

ids= [
       [234, 235, 236],
       [237, 238, 239, 240],
       [241, 242, 243, 244, 245]]

我想在 promise 内循环每个数组上的每个 id以获取每个 id 的价格,并在 promise 的结果中返回一个最低价格一个预期结果的每个数组示例

priceMin= [
            [price: 100] // min price id 235, 
            [price: 120], // min price id 238
            [price: 180] // min price id 244
           ]

我这样做但不工作

async getSkusAndProducts() {
      const id = this.ids;
      const app = { $axios: this.$axios };
      const promisesPrices = id.map((price) =>
        endPoint.getPrice(app, price)
      );
      const data = await Promise.all([
        promisesPrices.reduce((prev, curr) => (prev.id < curr.id ? prev : curr))
      ]);
      return data;
    }

请帮帮我谢谢

标签: javascript

解决方案


我想您正在使用axios. 为了模拟那部分,让我首先为您实现模拟功能,endPoint.getPrice()如下所示。

/* dummy function to mock your axios call */
function getPrice (ids) {
  const prices = {
    "234": 300,
    "235": 100,
    "236": 400,
    "237": 140,
    "238": 120,
    "239": 150,
    "240": 310,
    "241": 210,
    "242": 500,
    "243": 400,
    "244": 180,
    "245": 192,
  };
  return new Promise((resolve, reject) => {
    resolve(ids.map(id => prices[id]));
  });
}

这将获取您的ids数组并返回价格表Promise。您的 axios 应用程序也会返回Promise. 所以它是相似的。您可以看到它是如何工作的,如下所示:

getPrice(ids[0]).then(console.log);
getPrice(ids[1]).then(console.log);
getPrice(ids[2]).then(console.log);

现在,你的代码;

const promisesPrices = id.map((price) =>
        endPoint.getPrice(app, price)
);

返回数组,Promises程序继续执行下一行,无需等待从服务器获取数据。因此,您将无法实际处理以下行中的价格数据。

在这种情况下,最简单的方法是将回调传递给异步函数:

getPrice(id).then(prices => ({ price: Math.min(...prices) }))

当异步任务完成(即解决)时,价目表被传递给回调。并且价格数组现在通过Math.min()价差运算符传递给。

这是您的getSkusAndProduct(). 我也利用它Math.min()来获得最低的价格。

async function getSkusAndProducts (ids) {
  const minPrices = await Promise.all(ids.map(id =>
    getPrice(id).then(prices => ({ price: Math.min(...prices) }))
  ));
  return minPrices;
}

实际上,上面的代码是多余的。写关键字await实际上并不等待。它仍然返回数组Promise并将其设置为minPrices. 这只是编写回调样式的另一种方式,例如.then(callback)两行。在这种情况下,我们不想将结果分配给minPrices回调,因此我们可以简单地直接返回数组,Promise如下所示。请注意,您不需要async修饰符,因为您没有使用await. 它简单而美丽!

function getSkusAndProducts (ids) {
  return Promise.all(ids.map(id =>
    getPrice(id).then(prices => ({ price: Math.min(...prices) }))
  ));
}

您可以运行并查看下面的完整代码。我使用getSkusAndProducts()下面的冗余版本,因为使用minPrices变量可能看起来更容易阅读。替换为较短的版本并确认两者的工作方式相同。

const ids = [
  [234, 235, 236],
  [237, 238, 239, 240],
  [241, 242, 243, 244, 245]
];

/*
 * dummy function to mock your axios call
 * that returns Promise
 */
function getPrice (ids) {
  const prices = {
    "234": 300,
    "235": 100,
    "236": 400,
    "237": 140,
    "238": 120,
    "239": 150,
    "240": 310,
    "241": 210,
    "242": 500,
    "243": 400,
    "244": 180,
    "245": 192,
  };
  return new Promise((resolve, reject) => {
    resolve(ids.map(id => prices[id]));
  });
}

async function getSkusAndProducts (ids) {
  const minPrices = await Promise.all(ids.map(id =>
    getPrice(id).then(prices => ({ price: Math.min(...prices) }))
  ));
  return minPrices;
}

(async function main () {
  const minData = await getSkusAndProducts(ids);
  console.log(minData);
})();

/* or equivalently you can simply run as */
// getSkusAndProducts(ids).then(console.log);

附录

要回答您的附加评论,您可以运行以下版本 2 代码。

function getSkusAndProductsV2 (ids) {
  return Promise.all([
    ...(ids.map(id => getPrice(id))),
    ...(ids.map(id => getPrice(id).then(prices => ({ price: Math.min(...prices) }))))
  ])
}

第一个getPrice()将在解析时简单地返回价格数组。带有 的第二个then(callback)将返回最低价目表,如下所示:

[
  [ 300, 100, 400 ],
  [ 140, 120, 150, 310 ],
  [ 210, 500, 400, 180, 192 ],
  { price: 100 },
  { price: 120 },
  { price: 180 }
]

推荐阅读