【问题标题】:How to create "li"s based on "fetch" result如何根据“fetch”结果创建“li”
【发布时间】:2019-08-01 02:05:16
【问题描述】:

我正在尝试通过参考他们在https://dog.ceo/dog-api/documentation/ 的文档来从该网站提取一些数据

我正在尝试检索犬种列表并创建一个列表。我正在使用 javaScript 的“获取”

let dog_list = [];
fetch('https://dog.ceo/api/breeds/list/all')
  .then(response => {
    if (response.ok) {
      return response.json();
    } else {
      throw new Error(response.statusText);
    }
  })
  .then(data => dog_list = data.message)
const container = document.getElementById("container");
for (dog in dog_list) {
  let li = document.createElement("li");
  let node = document.createTextNode(dog);
  li.appendChild(node);
  container.appendChild(li);
}
<!DOCTYPE html>
<html lang="en">

<head>
  <title>Dog Breed List</title>
</head>

<body>
  <ul id="container"></ul>
  <script src="dog_breed.js"></script>
</body>

</html>

我在第二个“then”遇到问题,我不知道如何将 json 对象转换为数组并将它们显示为

  • 狗1
  • 狗2
  • 狗3

【问题讨论】:

  • for 循环移动到回调中。 .then(data =&gt; { dog_list = data.message; const container = document.getElementById("container"); for (dog in dog_list) {....} })
  • 你的循环在狗被抓取之前运行..

标签: javascript


【解决方案1】:

只需在创建 dog_list 的回调中构造 li...

这样的……

let dog_list = [];
const container = document.getElementById("container");
fetch('https://dog.ceo/api/breeds/list/all')
    .then(response => {
        if (response.ok) {
            return response.json();
        } else {
            throw new Error(response.statusText);
        }
    })
    .then(data => {
        dog_list = data.message;
        for (dog in dog_list) {
            let li = document.createElement("li");
            let node = document.createTextNode(dog);
            li.appendChild(node);
            container.appendChild(li);
        }
    });

为什么需要在 Promise 处理程序中构造生成的 DOM 结构?

因为完整 fetch(/*...*/).then(/*...*/).then(/*...*) 块将被执行 asynchronously

无需等待该代码完成,主线('全局')代码将从之后的行继续执行,在您的情况下,它正在获取容器并开始添加 li 元素。问题是此时来自 fetch 调用的响应的处理甚至都不会开始(即使已经执行了 fetch 并返回了结果),因此dog_list 将是空的。

【讨论】:

    【解决方案2】:

    您也可以对asyncawait 进行相同的尝试。 请看下面。

    const url = 'https://dog.ceo/api/breeds/list/all';
    
    async function Main() {
      const dog_data = await getDogData(url).catch(catchError);
      const dog_list = dog_data.message;
      const container = document.getElementById("container");
      for (dog in dog_list) {
        const node = createHTMLElement('li', dog);
        container.appendChild(node);
      }
    }
    
    function catchError(err) {
      console.log('Error ', err);
    }
    
    function createHTMLElement(_node, data) {
      let li = document.createElement("li");
      li.textContent = dog;
      return li;
    }
    
    async function getDogData(_url) {
      const response = await fetch(_url);
      return await response.json();
    }
    
    Main();
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <title>Dog Breed List</title>
    </head>
    
    <body>
      <ul id="container"></ul>
    
    </body>
    
    </html>

    【讨论】:

    • 哇,在此之后的阅读路径清晰,我在 JS 中还是比较新的,从不知道 async 和 await 存在。谢谢你的光。
    【解决方案3】:

    由于.then 中的回调是异步的,您可以在.then 回调中填充列表,否则dog_list 在循环运行时仍然是一个空数组:

    fetch('https://dog.ceo/api/breeds/list/all')
      .then(response => {
        if (response.ok) {
          return response.json();
        } else {
          throw new Error(response.statusText);
        }
      })
      .then(data => populate(data.message));
    function populate(dog_list){
        const container = document.getElementById("container");
        for (dog in dog_list) {
          let li = document.createElement("li");
          let node = document.createTextNode(dog);
          li.appendChild(node);
          container.appendChild(li);
        }
    }
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <title>Dog Breed List</title>
    </head>
    
    <body>
      <ul id="container"></ul>
    </body>
    
    </html>

    【讨论】:

    • 感谢将“填充”部分分离到另一个函数中以实现可维护性。
    猜你喜欢
    • 2017-06-12
    • 2020-04-28
    • 1970-01-01
    • 1970-01-01
    • 2012-02-11
    • 2016-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多