在 Nextjs 中未发送响应即可解析 API
Posted
技术标签:
【中文标题】在 Nextjs 中未发送响应即可解析 API【英文标题】:API resolved without sending a response in Nextjs 【发布时间】:2020-06-26 06:46:06 【问题描述】:我必须在我的 nextjs 项目中进行相同的更改,因为我的 enpoint API 不支持很多调用,我想每 3 分钟从原始数据中刷新一次。
我从 nextjs 实现了 API:我创建了一个 pages/api/data
并在内部调用我的端点,并在我的getInitialProps
内部索引调用数据文件。
get 工作正常,但我有 2 个问题:
1:我收到一条警告消息:
在未发送 /api/data 响应的情况下解析 API,这可能会导致请求停止。
2: 3 分钟后不会重新加载数据。我想这是因为 Cache-Control 值...
这是我的代码:
页面/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;
【问题讨论】:
你试过等待 getData() 吗? 嗨,Alessio,我尝试等待,警报消息消失了!但数据现在返回 4 次... 【参考方案1】:You should return a Promise and resolve/reject it.
例子:
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();
resolve(); // in case something goes wrong in the catch block (as vijay commented)
);
);
;
【讨论】:
如果出现错误,答案中的代码可能会抛出 UnhandledPromiseRejectionWarning。在 catch 块中你应该这样做: res.status(405).end();返回解析() 从异步函数返回一个承诺是多余的。最好在getData
上使用await
,放弃所有嵌套,并返回您喜欢的任何值,而不是resolve
ing。
我完全同意在 async
函数中返回显式 Promise
并不总是必要的。但在我看来,如果我们使用await
,则返回没有任何用处。这里的问题是 NextJS 只想要该函数的一些返回值,不管它是什么。返回 data.someValue
之类的内容可能会让人感到困惑。
我遇到了同样的错误。我忘了在我的 api 默认函数中的异步函数前面添加 await
。【参考方案2】:
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();
【讨论】:
【参考方案3】:您可以使用 'next-connect' 库,它消除了在这种情况下返回承诺的必要性。如果你喜欢express.js
的route->middleware->endpoint
模式,这个库就是你要找的。它还提供开箱即用的全局错误处理! [next-connect docs]
例子:
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")
)
【讨论】:
以上是关于在 Nextjs 中未发送响应即可解析 API的主要内容,如果未能解决你的问题,请参考以下文章
AppCompatActivity 中未解析的 Android Activity Results API 引用