【问题标题】:How to sequence the .then() calls in a specific order? [duplicate]如何按特定顺序对 .then() 调用进行排序? [复制]
【发布时间】:2020-12-01 08:39:50
【问题描述】:

我对承诺的概念相当陌生,我正在尝试建立一个简单的口袋妖怪列表(又名 pokedex)。我正在使用以下代码。

我希望根据宠物小精灵的指示列出它们的名称,我不希望顺序受到干扰。我目前使用的代码不保证这个功能。

在forEach() 方法中,fetch() 调用不会以任何方式链接,因此这取决于首先收到哪个响应,但我希望索引x 的then() 在then() 之前执行索引x+1。

const container = document.querySelector(".container");

fetch('https://pokeapi.co/api/v2/pokemon?limit=150')
  .then(response => response.json())
  .then(json => {
    json.results.forEach((el, index) => {
      fetch(el.url)
        .then(response => response.json())
        .then(json => {
          const pokemonName = el.name;
          const pokemontype = json.types[0].type.name;
          container.innerHTML += `(${index+1}) ${pokemonName} - ${pokemontype} <br>`;
        })
    })
  })
&lt;div class="container"&gt;&lt;/div&gt;

更新:下面是我使用Promise.all()的解决方案

const container = document.querySelector(".container");

fetch('https://pokeapi.co/api/v2/pokemon?limit=150')
  .then(response => response.json())
  .then(json => {
    const responseArr = [];
    json.results.forEach(el => {
      responseArr.push(fetch(el.url));
    });

    return Promise.all(responseArr);
  })
  .then(responses => {
    const jsonArr = [];
    responses.forEach(el => {
      jsonArr.push(el.json());
    });

    return Promise.all(jsonArr);
  })
  .then(jsons => {
    jsons.forEach((json, index) => {
      const pokemonName = json.name;
      const pokemonType = json.types[0].type.name;
      container.innerHTML += `(${index+1}) ${pokemonName} - ${pokemonType} <br>`;
    });
  })
&lt;div class="container"&gt;&lt;/div&gt;

【问题讨论】:

标签: javascript promise es6-promise


【解决方案1】:

您可以使用Promise.all 并传递第一个 API 调用的结果,这将按照请求的顺序返回响应:

const container = document.querySelector(".container");

fetch('https://pokeapi.co/api/v2/pokemon?limit=150')
  .then(response => response.json(), e => {
    console.error(e);
    throw e;
  })
  .then(json => {
    Promise.all(json.results.map(el => fetch(el.url)))
      .then(arr => {
        arr.map(response => response.json())
          .forEach((result, index) => {
            result.then(el => {
              const pokemonName = el.name;
              const pokemontype = el.types[0].type.name;
              container.innerHTML += `(${index+1}) ${pokemonName} - ${pokemontype} <br>`;
            })
          })
      }).catch(e => {
        console.error(e)
        throw e;
      });
  }).catch(e => {
    console.error(e)
    throw e;
  });
&lt;div class="container"&gt;&lt;/div&gt;

【讨论】:

  • 我认为您的解决方案并不完全正确,因为您只使用了一次 Promise.all()。您已经假设 response.json() 将遵循顺序,并且 json 承诺将按顺序返回。请查看我已将解决方案粘贴在那里的更新问题。在那里我使用了 Promise.all() 两次。我做错了吗?
  • arr.map(response =&gt; response.json()).forEach((result, index) =&gt; {result.then(......... 这里result.then()可能不按顺序,第一个被执行的会先打印出来。
  • 您的代码不起作用尝试将 api 端点更改为 https://pokeapi.co/api/v2/pokemon?limit=15 并查看订单如何混乱。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-11-01
  • 1970-01-01
  • 2020-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多