JavaScript 停止并行函数调用
JavaScript Stall Parallel Function Calls
我创建了一个 TokenService
class,目的是 return 访问令牌。 getToken
函数检查令牌是否已过期,如果为真,它将尝试在给定 refreshToken 的情况下获取新的 accessToken。但是,重要的是只有一个请求会尝试刷新令牌。因此,如果函数被并行调用,它需要等到第一个调用完成并且 return 所有其他调用的结果。
这是我当前的实现:
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
指示当前是否有正在进行的刷新请求。我不确定如何从这里开始。我如何等待请求完成并 return 结果?
您必须先通过 this
来引用 isRefreshing
- 它不是独立的标识符。
刷新令牌时,将Promise的结果分配给class上的属性。这将使 getToken
到 return 的进一步调用,如果 Promise 存在。如果它不存在,并且当前令牌已过期,则生成另一个。
因为你有时Promise.resolve(null)
,你有时return 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;
}
}
我创建了一个 TokenService
class,目的是 return 访问令牌。 getToken
函数检查令牌是否已过期,如果为真,它将尝试在给定 refreshToken 的情况下获取新的 accessToken。但是,重要的是只有一个请求会尝试刷新令牌。因此,如果函数被并行调用,它需要等到第一个调用完成并且 return 所有其他调用的结果。
这是我当前的实现:
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
指示当前是否有正在进行的刷新请求。我不确定如何从这里开始。我如何等待请求完成并 return 结果?
您必须先通过 this
来引用 isRefreshing
- 它不是独立的标识符。
刷新令牌时,将Promise的结果分配给class上的属性。这将使 getToken
到 return 的进一步调用,如果 Promise 存在。如果它不存在,并且当前令牌已过期,则生成另一个。
因为你有时Promise.resolve(null)
,你有时return 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;
}
}