我創建了一個TokenService旨在回傳訪問令牌的類。該getToken函式檢查令牌是否已過期,如果為真,它將嘗試在給定 refreshToken 的情況下獲取新的 accessToken。但是,重要的是只有一個請求發出嘗試重繪 令牌。因此,如果函式被并行呼叫,它需要等到第一個呼叫完成并為所有其他呼叫回傳該結果。
這是我目前的實作:
class TokenService {
private isRefreshing: boolean = false
public getToken = async (): Promise<string> => {
const accessToken = window.localStorage.getItem('accessToken')
if (!accessToken) return Promise.resolve(null)
// Check if token has expired
const { exp } = JSON.parse(atob(accessToken.split('.')[1]))
if (new Date() < new Date(exp * 1e3))
return Promise.resolve(accessToken)
if (this.isRefreshing) {
// Wait for request to finish and return result
}
// Refresh token
this.isRefreshing = true
const refreshedAccessToken = await this.refreshToken()
return Promise.resolve(refreshedAccessToken)
}
}
我添加了一個標志isRefreshing,指示當前是否正在進行重繪 請求。我不確定如何從這里出發。如何等待請求完成并回傳結果?
uj5u.com熱心網友回復:
您必須先isRefreshing通過參考this- 它不是一個獨立的識別符號。
重繪 令牌時,將 Promise 的結果分配給類的屬性。getToken如果存在,這將允許進一??步呼叫回傳該 Promise。如果它不存在,并且當前令牌已過期,則生成另一個。
因為你有時會這樣做Promise.resolve(null),有時會回傳null,而不是字串,所以你應該getToken適當地更改型別簽名。
class TokenService {
private tokenPromise: null | Promise<string> = null;
public getToken = async (): Promise<string | null> => {
const accessToken = window.localStorage.getItem('accessToken')
if (!accessToken) return null;
// Check if token has expired
const { exp } = JSON.parse(atob(accessToken.split('.')[1]))
if (new Date() <= new Date(exp * 1e3)) {
// no need to retrieve another
return accessToken;
}
if (this.tokenPromise) return this.tokenPromise;
this.tokenPromise = this.refreshToken()
.catch((error) => {
window.localStorage.removeItem('accessToken');
return null;
})
.finally(() => {
this.tokenPromise = null;
});
return this.tokenPromise;
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/437284.html
標籤:javascript 打字稿 承诺
