如何从函数中返回fetch API的结果?

13

我想从一个函数中返回fetch API的结果,但是我得到了undefined,并且这个函数没有返回我获取的数据:

function func() {
    fetch('https://randomuser.me/api/?results=10')
    .then(response => response.json())
    .then(json => (json.results))
}

let users = func()

console.log(users);


使用async和await - Ullas Hunka
@UllasHunka,你有没有异步/等待的想法?因为我不想在函数内获取结果。也许它是一个类方法! - Mohammad
5个回答

19

Fetch 是异步的并返回一个 promise。没有办法同步地获取 fetch 返回的数据。它也无法返回 users ,因为函数需要同步返回,但是 users 的数据不可用。函数在 Fetch 从 url 获取响应之前就已经返回了。这是可以接受的,因为所有事情都是这样做的,而且仍然有效。

处理此问题最灵活的方法是只需从函数中返回 promise。然后,您可以在 promise 结果上使用 then() 并在其中执行任何需要执行的操作:

function func(url) {
    return fetch(url)  // return this promise
    .then(response => response.json())
    .then(json => (json.results))
}

func('https://randomuser.me/api/?results=10')
.then(users => console.log(users))  // call `then()` on the returned promise to access users
.catch(err => /* handle errors */)

1
非常感谢您提供这个解释清晰的答案和非常有用的代码片段! - davidysoards

1
由于此调用是异步的,当您将其作为响应记录时,usersundefined,因为服务器尚未收到响应,您需要执行以下操作。您可以在func调用中添加then,当服务器接收到响应时,它将记录用户。

function func(url) {
    return fetch(url)  // return this promise
    .then(response => response.json())
    .then(json => (json.results))
}

func('https://randomuser.me/api/?results=10')
.then(users => console.log(users))


变量Users可以移动到函数块中,然后进行赋值,最后函数可以返回该变量。这样就少了一个全局变量 :-) - Nnanyielugo

1
一个fetch的例子可以如下所示:
loadJSON('https://randomuser.me/api/?results=10');
async function loadJSON(fname) {
    var response = await fetch(fname)
    var j =  await response.json()
    document.getElementById('jsondemo1').value = j.name
    document.getElementById('jsondemo2').value = j.year
}

没有异步和等待:

fetch(url).then(response => response.json())
  .then(result => console.log('success:', result))
  .catch(error => console.log('error:', error));

我可以不使用任何函数直接使用那个结果吗?比如说,我想在一个类的构造方法中使用它。 - Mohammad
已更新答案,请查看。 - Ullas Hunka
我明白了,考虑一下:例如,我有一个公共的 fetch_data 函数,我想在应用程序的所有部分中使用它。有时我想在函数内或函数外获取 API,但是我不能使用 async/await。你有什么解决方案吗? - Mohammad

0

你的函数似乎没有返回值。如果没有返回值,你的函数将会被评估为 undefined。

返回你的 fetch 调用结果(例如:json.results),并告诉我们发生了什么。


这不是原因,而是因为API没有收到响应。 - Paul Fitzgerald
我不认为是这样的。then 是一个 Promise 语法,第二个 then 调用会在 Promise 被解决或拒绝后执行,在这种情况下,错误将被转发到 catch 块。 - Nnanyielugo
我认为这是 :-) 那个函数正在返回一个值 - 像这样编写的箭头函数有一个隐式返回 - 这里有一些阅读材料供您参考 - https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/Arrow_functions - Paul Fitzgerald
他可以尝试在函数中记录第二个then块的响应,以此来尝试。在函数内部记录调用的结果。 - Nnanyielugo
好的,让我们试试这个。将一个变量初始化为未定义。然后在第二个 then 块中,将调用结果分配给未定义的变量,然后在主函数作用域中返回该变量。这可能是一个作用域问题。 - Nnanyielugo
@Nnanyielugo 那样不行,该函数是同步返回的,因此它会在then()中设置值之前返回未定义的值。 - Mark

-4
你需要将 fetch 包装在一个 Promise 中,并使用 json 数据解决它。例如:
function func(url) {
    return new Promise((resolve, reject) => { 
        fetch(url)  // return this promise
        .then(response => response.json())
        .then(json => resolve((json.results)))
    });
}

func('https://randomuser.me/api/?results=10')
    .then(users => console.log(users))

1
then 已经返回了一个 Promise,不需要再包装成另一个 Promise。只需要添加 return 即可。 - JojOatXGME
添加return语句仍然会从函数返回undefined。为了从函数返回数据,它需要被包装在Promise中。 - Faiz
1
这个其他答案对我有用。只需点击“运行代码片段”。 - JojOatXGME
我的错。你能否取消这个踩的操作?我会删除这个回答。 - Faiz
有趣的是,只要答案没有被编辑,我似乎无法撤销投票。不过,我认为这并不是一个问题。实际上,是否有理由先删除投票呢? - JojOatXGME

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接