如何基于“提取”结果创建“ li”

时间:2019-03-10 17:19:57

标签: javascript

我正在尝试通过参考他们在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对象转换为数组并将其显示为

  • dog1
  • dog2
  • dog3

3 个答案:

答案 0 :(得分:2)

只需在创建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 handler中构造最终的DOM结构?

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

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

答案 1 :(得分:2)

由于.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>

答案 2 :(得分:1)

您也可以使用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>