You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在另一个函数内调用异步函数并获取响应?API调用报错求助

问题分析与解决方案

首先,你的问题核心是没有正确处理fetch的异步特性,这也是前端新手常踩的坑,我来一步步帮你解决:

1. 为什么getCategory()返回undefined?

fetch是异步操作,它不会阻塞代码执行——当你调用getCategory()时,函数会立刻执行到fetch语句,然后直接返回(默认返回undefined),根本没等API请求完成、拿到数据。

要解决这个问题,你需要让getCategory()返回fetch生成的Promise,这样外部调用时就能通过.then()或async/await等待异步结果:

function getCategory() {
  // 关键:返回整个fetch Promise链
  return fetch('https://api.chucknorris.io/jokes/categories')
    .then(res => {
      // 先检查响应是否成功(HTTP状态码200-299)
      if (!res.ok) {
        throw new Error(`请求失败,状态码:${res.status}`);
      }
      return res.json();
    })
    .then(data => {
      console.log(data); // 这里依然可以打印数据
      return data; // 把数据返回给调用者
    })
    .catch(err => {
      console.error('获取分类出错:', err);
      throw err; // 抛出错误,让调用者可以处理
    });
}

现在调用getCategory()时,就可以拿到有效的分类数据了:

// 示例:在DOM加载完成后获取分类
document.addEventListener('DOMContentLoaded', () => {
  getCategory().then(categories => {
    // 这里可以用categories做任何事,比如渲染到页面
    console.log('拿到的分类列表:', categories);
  }).catch(err => {
    // 处理错误,比如提示用户
    alert('获取分类失败,请检查网络');
  });
});

2. 为什么generateRandomQuotes(e)会抛出JSON解析错误?

这个错误"Unexpected token u in JSON at position 0"几乎可以肯定是因为你尝试解析undefined("u"是undefined的首字母)。大概率是你在调用getCategory()时,直接用了它的返回值(也就是之前的undefined)去做JSON处理,或者请求随机笑话时的响应为空/无效。

我们同样用正确的异步方式改写generateRandomQuotes,并添加错误处理:

function generateRandomQuotes(selectedCategory) {
  return fetch(`https://api.chucknorris.io/jokes/random?category=${selectedCategory}`)
    .then(res => {
      if (!res.ok) {
        throw new Error(`请求笑话失败,状态码:${res.status}`);
      }
      return res.json();
    })
    .then(quoteData => {
      console.log(quoteData);
      return quoteData;
    })
    .catch(err => {
      console.error('生成笑话出错:', err);
      throw err;
    });
}

然后在事件监听里正确调用:

document.addEventListener('DOMContentLoaded', () => {
  // 假设你有一个按钮触发生成笑话
  const quoteBtn = document.getElementById('quoteBtn');
  
  quoteBtn.addEventListener('click', (e) => {
    e.preventDefault();
    // 先确保你已经拿到了选中的分类(这里示例用'animal',替换成实际选中值)
    const category = 'animal';
    
    generateRandomQuotes(category).then(quote => {
      // 把笑话渲染到页面
      document.getElementById('quoteDisplay').textContent = quote.value;
    }).catch(err => {
      document.getElementById('quoteDisplay').textContent = '获取笑话失败,请重试';
    });
  });
});

可选:用async/await让代码更直观

如果你觉得.then()链看起来繁琐,可以用async/await语法改写,逻辑更清晰:

async function getCategory() {
  try {
    const res = await fetch('https://api.chucknorris.io/jokes/categories');
    if (!res.ok) {
      throw new Error(`请求失败,状态码:${res.status}`);
    }
    const data = await res.json();
    console.log(data);
    return data;
  } catch (err) {
    console.error('获取分类出错:', err);
    throw err;
  }
}

async function generateRandomQuotes(selectedCategory) {
  try {
    const res = await fetch(`https://api.chucknorris.io/jokes/random?category=${selectedCategory}`);
    if (!res.ok) {
      throw new Error(`请求笑话失败,状态码:${res.status}`);
    }
    const quoteData = await res.json();
    console.log(quoteData);
    return quoteData;
  } catch (err) {
    console.error('生成笑话出错:', err);
    throw err;
  }
}

// 调用示例(注意要在async函数里用await)
document.addEventListener('DOMContentLoaded', async () => {
  try {
    const categories = await getCategory();
    console.log('分类列表:', categories);
  } catch (err) {
    alert('获取分类失败');
  }
});

内容的提问来源于stack exchange,提问作者Arne

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:29:58