在 Nextjs 中未发送响应的 API 已解析

IT技术 javascript node.js reactjs rest next.js
2021-04-14 03:55:29

我必须在我的 nextjs 项目中进行相同的更改,因为我的 enpoint API 不支持很多调用,我想每 3 分钟刷新一次原始数据。

我从 nextjs 实现了 API:我创建了一个pages/api/data并在内部调用了我的端点,并在我的getInitialProps内部索引调用中调用了数据文件。

get 工作正常,但我有两个问题:

1:我有警告消息说:

API 在不发送响应 /api/data 的情况下解析,这可能会导致请求停止。

2:它在 3 分钟后没有重新加载数据......我认为这是因为缓存控制值......

这是我的代码:

页面/API/数据

import { getData } from "../../helper";

export default async function(req, res) {
  getData()
    .then(response => {
      res.statusCode = 200
      res.setHeader('Content-Type', 'application/json');
      res.setHeader('Cache-Control', 'max-age=180000');
      res.end(JSON.stringify(response))
    })
    .catch(error => {
      res.json(error);
      next();
    });
};

页/索引

import React, { useState, useEffect } from "react";
import fetch from 'isomorphic-unfetch'

const Index = props => {

  return (
    <>Hello World</>
  );
};

 Index.getInitialProps = async ({ res }) => {
  const response = await fetch('http://localhost:3000/api/data')
  const users = await response.json()
  return { users }
};

export default Index;
3个回答

您应该返回一个 Promise 并解决/拒绝它。

例子:

import { getData } from "../../helper";

export default async function(req, res) {
  return new Promise((resolve, reject) => {
    getData()
      .then(response => {
        res.statusCode = 200
        res.setHeader('Content-Type', 'application/json');
        res.setHeader('Cache-Control', 'max-age=180000');
        res.end(JSON.stringify(response))
        resolve();
      })
      .catch(error => {
        res.json(error);
        res.status(405).end();
        return resolve(); //in case something goes wrong in the catch block (as vijay) commented
      });
  });
};
我有同样的错误。我忘了await在我的 api 默认函数中的 async 函数前面添加
2021-05-25 03:55:29
我完全同意Promiseasync函数中返回显式并不总是必要的但在我看来,如果我们使用await. 这里的问题是 NextJS 只想要该函数的一些返回值,它是什么并不重要。data.someValue在这里返回类似的东西可能会令人困惑。
2021-05-31 03:55:29
从异步函数返回Promise是多余的。最好使用awaiton getData,抛弃所有嵌套,并返回您喜欢的任何值而不是resolveing。
2021-06-09 03:55:29
如果出现错误,答案中截断的代码可能会抛出 UnhandledPromiseRejectionWarning。在 catch 块中你应该做: res.status(405).end(); 返回解决()
2021-06-21 03:55:29
import { getData } from "../../helper";

export default async function (req, res) {
  try {
    const response = await getData();
    res.statusCode = 200;
    res.setHeader('Content-Type', 'application/json');
    res.setHeader('Cache-Control', 'max-age=180000');
    res.end(JSON.stringify(response));
  }

  catch (error) {
    res.json(error);
    res.status(405).end();
  }
}

您可以使用“next-connect”库,它消除了在这种情况下返回Promise的必要性。如果你喜欢express.jsroute->middleware->endpoint模式,这个库就是你要找的。它还提供开箱即用的全局错误处理![下一个连接文档]

例子:

import nc from 'next-connect'

function onError(err, req, res, next) {
  logger.log(err);

  res.status(500).end(err.toString());
  // OR: you may want to continue
  next();
}

const handler = nc({ onError });

handler
  .use((req, res, next) => {
    if(!req.user){
      throw new Error("oh no!");
      // or use next
      next(Error("oh no"));
    }
  })
  .get((req, res) => {
    res.end("success")
  })