【问题标题】:Asynchronous processing of arrays (Promise.all or for..of)数组的异步处理(Promise.all 或 for..of)
【发布时间】:2021-04-27 01:10:21
【问题描述】:

我知道这方面的信息很多,我也读过几篇文章,但我还在徘徊。

我有一组 HTTP 请求 url。数组中每个元素的顺序非常重要。我想通过获取这些请求 url 来获得响应,并将响应按照与原始数组相同的顺序放置。

下面是我写的代码。我认为使用 promise.all 是正确的。我们发现 promise.all 可以并行处理数组,但不能保证顺序。 (这是正确的吗?)

const getAllImagePaths = async urls => {
  let copyPaths = [];

  try {
    const data = await Promise.all(urls.map(url => fetch(url)));

    for (let item of data) {
      const { url } = item;
      copyPaths.push(url);
    }

    return copyPaths;
  } catch (err) {
    const { response } = err;

    if (response) alert(MESSAGES.GET_PHOTOS_FAIL);
  }
};

所以我使用 for..of 语句修改了代码。

const getAllImagePaths = async urls => {
  let copyPaths = [];

  try {
    for(let url of urls) {
      const res = await fetch(url);
      const json = await res.json();
      const data = json.parse();

      const { url } = data;

      copyPaths.push(data);
    }

    return copyPaths;
  } catch (err) {
    const { response } = err;

    if (response) alert(MESSAGES.GET_PHOTOS_FAIL);
  }
};

但是,当使用for of语句时,数据的响应类型是'cors'。

所以要解决这个问题,我是否应该将数据更改为 json,然后再次解析 json 以使用数据?我觉得这很奇怪。这是因为我只想在数组的响应对象中包含名为“url”的信息。

【问题讨论】:

  • "我们发现 promise.all 可以并行处理数组,但不能保证排序。(这是正确的吗?)" — 不。不能保证 promise 解析的顺序,但是什么Promise.all 承诺解决它会按照它们进入的相同顺序处理所有结果。
  • "我们发现 promise.all 可以并行处理数组,但不能保证顺序。(正确吗?)"不,不是
  • "但是,当使用for of语句时,数据的响应类型为'cors'。" — 我没有时间构建测试用例,但我希望在与 const 相同的范围内重新声明 url 时会出错。
  • 如果您从Promise.all 获得的data 不按顺序排列,则使用for-of 循环它并将每个条目推入新数组也不会按顺序排列。

标签: javascript


【解决方案1】:

我们发现 promise.all 可以并行处理数组,但不能保证顺序。 (这是正确的吗?)

不,这是不正确的。您在履行Promise.all 承诺时获得的结果数组与输入数组的顺序相同,无论输入承诺的结算顺序如何。这是一个例子:

function delayedValue(ms, value) {
    return new Promise(resolve => {
        setTimeout(() => {
            console.log(`Resolving with ${value}`);
            resolve(value);
        }, ms);
    });
}

async function example() {
    const results = await Promise.all([
        delayedValue(100, 1),
        delayedValue(10,  2),
        delayedValue(200, 3),
    ]);
    console.log(`results: ${results}`);
}

example();

所以你可以直接使用结果:

const getAllImagePaths = async urls => {
  try {
    const data = await Promise.all(urls.map(url => fetch(url)));
    return data;
  } catch (err) {
    const { response } = err;

    if (response) alert(MESSAGES.GET_PHOTOS_FAIL);
  }
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-08-25
    • 2020-11-16
    • 2020-09-04
    • 2022-01-01
    • 2019-12-21
    • 2017-02-26
    • 1970-01-01
    • 2014-02-13
    相关资源
    最近更新 更多