如何在 Next.js 中进行依赖提取 API 调用

How to make dependent fetch API calls in Next.js

我是初学者,正在努力更好地理解 API 调用。

我想调用检索所有书籍的圣经 api。 然后我需要调用与书 # 相同的 api 来检索请求书的所有章节。

然后我想显示书籍列表和章节。

为此,我制作了一个循环遍历书籍和 returns 章节的实用函数。这是它中断的地方。

我能够取回书籍并展示它们。但是我不知道如何进行第二个 API 调用。我一直收到无法序列化对象 Promise 的错误。

另外,下一步在此处控制台登录的最佳方式是什么?我不确定如何查看返回的内容。

这是我目前的情况:

export default function Home(props) {
  console.log(props);
  return (
    <div className="container">
      <div>{/** display books & chapters */}</div>
    </div>
  );
}

export async function getStaticProps() {
  // get all books
  const reqBooks = await fetch(`https://getbible.net/v1/web/books.json`);
  const resBooks = await reqBooks.json();
  // convert to array of objs
  const books = await Object.entries(resBooks);


  const chapters = await getChapters(books);

  return {
    props: {
      books,
      chapters,
    },
  };
}

// utility... loop through books and make api calls to get chapters for each book
async function getChapters(books) {
  const chaptersArr = [];

  books.map((item, idx) => {
    //
    let url = item[1].url;
    let bookChapters = fetch(url).then(response => response.json().then(data => data));
    arr.push(bookChapters);
  });
  return chaptersArr;
}

问题是您将承诺推入数组,而不是承诺中的值。您可以直接在地图中使用 return,然后使用 Promise.all 来获取值,而不是使用该数组。 (您也可以使用数组,但由于您使用的是地图,因此不需要它)。为了清楚起见,我将 getBooks 调用提升到它自己的函数中,但重要的变化是地图中 getChapters 中发生的事情:

async function getBooks () {
  const res = await fetch('https://getbible.net/v1/web/books.json')
  const json = await res.json()
  return Object.entries(json)
}

async function getChapters (books) {
  const chapters = await Promise.all(
    books.map(async (item) => {
      const url = item[1].url
      const res = await fetch(url)
      const json = await res.json()
      return json
    })
  )

  return chapters
}

export async function getStaticProps() {
  const books = await getBooks()
  const chapters = await getChapters(books)

  return {
    props: {
      books,
      chapters,
    },
  }
}

您可以在普通节点(假设 node-fetch 或类似的包)或 Next 之外的浏览器中测试它,例如:

getStaticProps().then(data => {
  console.log(JSON.stringify(data, null, 2))
})