簡體   English   中英

Promise 解析 function 返回未定義

[英]Promise resolving function returns undefined

我為我想使用的 API 編寫了一個實用程序包裝器。 包裝器處理請求構建和令牌獲取。

從'./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我可以理解,雖然我確實期望 function 參考或 promise。
我嘗試在 fetchUtil 和調用者之前添加asyncawait fetchUtil。 這給了我一個錯誤,沒有在未定義上調用等待。 我還嘗試將其重新編寫成一個根本不起作用的鈎子。
我需要組件的useEffect掛鈎中的數據:

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

    useEffect(() => {
        setChargehistory(getChargehistory)
        setInstallationreport(getInstallationreport)
    }, [])
}

為什么我變得undefined ,我該如何解決這個問題?

在您的fetchUtil function 內部,它以沒有返回值結束,這意味着您的fetchUtil function 將隱式返回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))

在這個 function 內部, (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);
}

因為我沒有完全訪問您的代碼的權限,所以仍然可能存在錯誤,但我希望這會有所幫助!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM