【发布时间】:2021-06-03 03:01:04
【问题描述】:
我为我想使用的 API 编写了一个 util 包装器。包装器处理请求构建和令牌获取。
从'./refreshToken'导入refreshToken
/**
* Fetch util handles errors, tokens and request building for the wrapped API calls
* @param {string} url Request URL e.g. /chargehistory
* @param {string} requestMethod Request Method [GET, POST, PUT, DELETE]
* @param {object} requestBody Request Body as JSON object
* @param {object} retryFn The caller function as object reference to retry
* @private This function is only used as util in this class
* @async
*/
const fetchUtil = (url, requestMethod, requestBody, retryFn) => {
// Block thread if the token needs to be refetched
if(sessionStorage.getItem('token') == null || Number(sessionStorage.getItem('token_expiration')) < new Date().getTime()) {
refreshToken()
}
let request = {
method: requestMethod,
headers: {
'Authorization': `Bearer ${sessionStorage.getItem('token')}`,
'Content-Type': 'application/json'
}
}
if(requestMethod === 'POST' || requestMethod === 'PUT') {
request.body = JSON.stringify(requestBody)
}
fetch(`${process.env.REACT_APP_API}${url}`, request)
.then(response => {
if(response.ok) {
return response.json()
} else if(response.status === 401) {
refreshToken().then(() => retryFn())
} else {
console.error(`Error on fetching data from API: ${response.status}, ${response.text}`)
}
})
.then(json => {
console.log(json)
return json
})
.catch(error => console.error(error))
}
一旦解决,这将起作用并将一些 json 打印到控制台。接下来我构建了函数来使用这个抽象:
/**
* Get a list of all completed charge sessions accessible by the current user matching the filter options.
*/
const getChargehistory = (installationId) => {
console.log(fetchUtil(`/chargehistory?options.installationId=${installationId}`, 'GET', {}, getChargehistory))
}
哪个打印 undefined 我可以理解,虽然我确实期望一个函数引用或一个承诺。
我尝试在 fetchUtil 和调用者之前添加async 和await fetchUtil。这给了我一个错误,没有在未定义上调用等待。我还尝试将其重新编写成一个根本不起作用的钩子。
我需要组件的 useEffect 钩子中的数据:
const Cockpit = () => {
const { t } = useTranslation()
const [chargehistory, setChargehistory] = useState(undefined)
const [installationreport, setInstallationreport] = useState(undefined)
useEffect(() => {
setChargehistory(getChargehistory)
setInstallationreport(getInstallationreport)
}, [])
}
为什么我会收到undefined,我该如何解决这个问题?
【问题讨论】:
-
在
fetchUtil函数内部,fetch之前需要一个return关键字:return fetch(...)。另请注意,您应该在fetchUtil函数中处理错误,或者只是抛出错误以允许调用代码捕获并处理错误。就个人而言,我会从fetchUtil函数中删除catch方法调用,并在调用fetchUtil函数的任何地方链接catch方法。 -
另一种解决方案是添加一个简单的回调函数作为参数并调用它,而不是在 promise 的最后一个
then函数中返回。
标签: javascript reactjs async-await state fetch-api