承诺解析函数返回未定义



我为想要使用的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我可以有点理解,虽然我确实期望一个函数引用或承诺。
我试着在fetchtil和调用者和awaitfetchtil之前添加async。这给了我一个错误,没有调用未定义的await。我也试着把它重写成一个根本不起作用的钩子。
我需要组件的useEffect钩子中的数据:

const Cockpit = () => {
const { t } = useTranslation()
const [chargehistory, setChargehistory] = useState(undefined)
const [installationreport, setInstallationreport] = useState(undefined)
useEffect(() => {
setChargehistory(getChargehistory)
setInstallationreport(getInstallationreport)
}, [])
}

为什么我得到undefined,我怎么能解决这个问题?

fetchUtil函数中,它以没有返回值结束,这意味着您的fetchUtil函数将隐式返回undefined

你说

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) // (1) 
return json
})
.catch(error => console.error(error))

在这个函数中,(1)部分工作得很好,对吗?

我想如果你像下面这样修改你的代码,它就可以工作了。

首先,像这样更新fetchUtil代码。返回获取。

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)
}
// return fetch here! it will return a promise object. 
return 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))
}

第二,像这样更新你的getChargehistory

const getChargehistory = async (installationId) => {
const result =  await fetchUtil(`/chargehistory?options.installationId=${installationId}`, 'GET', {}, getChargehistory)
console.log(result);
}

因为我没有完全访问你的代码,仍然可能有错误,但我希望这有助于!

最新更新