无法从JavaScript的Fetch函数中在HTML标签中返回字符串。

huangapple go评论74阅读模式
英文:

Can't return a string from a Fetch function in JavaScript in html tag

问题

以下是翻译好的部分:

功能正常的部分:

document.querySelector('#bt_funFact').addEventListener('click', async () => {
  norrisRandom();
})

async function norrisRandom() {
  fetch('https://api.chucknorris.io/jokes/random')
    .then(res => res.json())
    .then(data => {
      console.log(data.value)
      document.getElementById('funFact').innerHTML = data.value;
    })
}

出现问题的部分:

document.querySelector('#bt_funFact').addEventListener('click', async () => {
  document.getElementById('funFact').innerHTML = norrisRandom();
})

async function norrisRandom() {
  fetch('https://api.chucknorris.io/jokes/random')
    .then(res => res.json())
    .then(data => {
      console.log(data.value)
      return data.value;
    })
}

请注意,出现问题的部分在norrisRandom函数中使用了return语句,但这并不会直接返回数据给调用函数。因为fetch函数是异步的,所以norrisRandom函数会立即返回一个Promise,而不是等待数据加载完成后再返回数据。因此,你得到了"[object Promise]",而不是实际的数据。要解决这个问题,你需要等待fetch操作完成并返回数据后再设置innerHTML。你可以使用async/await来实现这一点,如下所示:

document.querySelector('#bt_funFact').addEventListener('click', async () => {
  const joke = await norrisRandom();
  document.getElementById('funFact').innerHTML = joke;
})

async function norrisRandom() {
  const response = await fetch('https://api.chucknorris.io/jokes/random');
  const data = await response.json();
  console.log(data.value);
  return data.value;
}

这样,norrisRandom函数将等待fetch操作完成,然后返回数据,从而解决了问题。

英文:

I'm looking to return a string in a html tag. (Chuck Norris joke from an API)
I succeed to display the value if I ask directly to display it in the function body.

But I don't succeed to return a string to display it later. I want to call only once the function so I can display the string in several areas.

What is working:

document.querySelector('#bt_funFact').addEventListener('click', async () => {
  norrisRandom();
})

async function norrisRandom() {
  fetch('https://api.chucknorris.io/jokes/random')
    .then(res => res.json())
    .then(data => {
      console.log(data.value)
      document.getElementById('funFact').innerHTML = data.value;
    })
}

But if I try to return the value like below, I get "[object Promise]" in html.

document.querySelector('#bt_funFact').addEventListener('click', async () => {
  document.getElementById('funFact').innerHTML = norrisRandom();
})

async function norrisRandom() {
  fetch('https://api.chucknorris.io/jokes/random')
    .then(res => res.json())
    .then(data => {
      console.log(data.value)
      return data.value;
    })
}

I can't figure out why it displays in function body and not by returning the value.

答案1

得分: 1

你面临的问题是因为norrisRandom()函数是异步的并且返回一个promise。当你尝试直接用norrisRandom()设置innerHTML时,你实际上将promise对象赋给了它,这就是为什么你在HTML中看到了“[object Promise]”。尝试这样做:

document.querySelector('#bt_funFact').addEventListener('click', async () => {
  const joke = await norrisRandom();
  document.getElementById('funFact').innerHTML = joke;
});

async function norrisRandom() {
  const response = await fetch('https://api.chucknorris.io/jokes/random');
  const data = await response.json();
  return data.value;
}
英文:

The issue you're facing is because the norrisRandom() function is asynchronous and returns a promise. When you try to set the innerHTML directly with norrisRandom(), you are assigning the promise object to it, which is why you see "[object Promise]" in the HTML. Try this

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

document.querySelector(&#39;#bt_funFact&#39;).addEventListener(&#39;click&#39;, async () =&gt; {
  const joke = await norrisRandom();
  document.getElementById(&#39;funFact&#39;).innerHTML = joke;
});

async function norrisRandom() {
  const response = await fetch(&#39;https://api.chucknorris.io/jokes/random&#39;);
  const data = await response.json();
  return data.value;
}

<!-- end snippet -->

答案2

得分: 1

事件监听器应该使用 awaitnorrisRandom() 返回的 promise 中提取值。你的代码将 Promise 本身放在了内部 HTML 中。

norrisRandom() 不需要声明为 async,因为 .then() 已经返回一个 promise。但你需要返回 .then() 链的值。

document.querySelector('#bt_funFact').addEventListener('click', async () => {
  document.getElementById('funFact').innerHTML = await norrisRandom();
})

function norrisRandom() {
  return fetch('https://api.chucknorris.io/jokes/random')
    .then(res => res.json())
    .then(data => {
      console.log(data.value)
      return data.value;
    })
}
英文:

The event listener should use await to extract the value from the promise returned by norrisRandom(). Your code is putting the Promise itself in the inner HTML.

norrisRandom() doesn't need to be declared async, since .then() returns a promise already. But you need to return the value of the .then() chain.

document.querySelector(&#39;#bt_funFact&#39;).addEventListener(&#39;click&#39;, async () =&gt; {
  document.getElementById(&#39;funFact&#39;).innerHTML = await norrisRandom();
})

function norrisRandom() {
  return fetch(&#39;https://api.chucknorris.io/jokes/random&#39;)
    .then(res =&gt; res.json())
    .then(data =&gt; {
      console.log(data.value)
      return data.value;
    })
}

答案3

得分: 0

你似乎不明白async关键字的作用,所以:

声明一个函数为async可以在其中使用await

这使得可以以同步的方式编写异步代码:

async function fn() {
    await one()
    await two()
    await three()
    console.log("完成!")
}

在功能上等同于:

function fn() {
    return one()
        .then(() => {
            return two()
        })
        .then(() => {
            return three()
        })
        .then(() => {
            console.log("完成!")
        })
}

注意async函数更容易阅读。

所以当你不打算在函数中使用await关键字时,声明一个函数为async没有意义!

让我们从修复你的norrisRandom函数开始:

async function norrisRandom() {
  const res = await fetch('https://api.chucknorris.io/jokes/random')
  const data = await res.json()

  return data.value  
}

然后在你的点击处理程序中像这样使用await

document.querySelector('#bt_funFact').addEventListener('click', async () => {
    document.getElementById('funFact').innerHTML = await norrisRandom();
})
英文:

You don't seem to understand what the async keyword is doing, so:

Declaring a function async makes it possible to use await inside of it.

This makes it possible to write asynchronous code in a synchronous fashion:

async function fn() {
    await one()
    await two()
    await three()
    console.log(&quot;done!&quot;)
}

Is functionally equivalent to:

function fn() {
    return one()
        .then(() =&gt; {
            return two()
        })
        .then(() =&gt; {
            return three()
        })
        .then(() =&gt; {
            console.log(&quot;done!&quot;)
        })
}

Notice how the async function is much easier to read?

So there's no point in declaring a function async when you're not going to use the await keyword inside of it!

Let's start by fixing your norrisRandom function:

async function norrisRandom() {
  const res = await fetch(&#39;https://api.chucknorris.io/jokes/random&#39;)
  const data = await res.json()

  return data.value  
}

Then use await inside your click handler like this:

document.querySelector(&#39;#bt_funFact&#39;).addEventListener(&#39;click&#39;, async () =&gt; {
    document.getElementById(&#39;funFact&#39;).innerHTML = await norrisRandom();
})

huangapple
  • 本文由 发表于 2023年7月11日 03:46:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/76656873.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定