如何按特定顺序对 .then() 调用进行排序? [复制]

Posted

技术标签:

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

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

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

forEach() 方法中,fetch() 调用不会以任何方式链接,因此这取决于首先收到哪个响应,但我希望索引xthen()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;

【问题讨论】:

将promise放入一个数组中,然后使用Promise.all()按照数组的顺序处理结果。 使用Promise.all()async/await 检查这个 - ***.com/questions/24586110/… 【参考方案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 并查看订单如何混乱。

以上是关于如何按特定顺序对 .then() 调用进行排序? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

如何使用python按特定顺序对文件名进行排序

如何对大量 csv 文件进行排序以按特定顺序读取它们?

按特定顺序对名称数组进行排序

使用比较器按特定顺序对对象列表进行排序

如何使用 NSFetchedResultsController 按字母顺序对 UITableView 进行排序?

按多个数组对 Tableview 行进行排序