如果您的应用程序具有多个并发API调用,并且您可能有想要停止和控制其触发的方案。我在谈论API服务的互斥体解决方案,该解决方案允许锁定和解锁API以控制Web服务。
假设我们的应用需要将API令牌传递到标头中以进行授权。我们希望在浏览器触发任何API之前获取此令牌。如果此令牌过期,我们将再次获取一个新令牌。浏览器中的所有其他API都应等待新令牌,然后触发。
如果您的应用程序具有多个并发API调用,并且您可能有想要停止和控制其触发的方案。我在谈论API服务的互斥体解决方案,该解决方案允许锁定和解锁API以控制Web服务。
假设我们的应用需要将API令牌传递到标头中以进行授权。我们希望在浏览器触发任何API之前获取此令牌。如果此令牌过期,我们将再次获取一个新令牌。浏览器中的所有其他API都应等待新令牌,然后触发。
首先,我们创建axios实例
import APILockService from '../APILockService';
import axios from 'axios';
function apiRequestLockInterceptor(config) {
if(APILockService.isLocked(config)) {
await APILockService.waitTillUnlocked();
}
return config;
}
const instance = axios.create();
instance.interceptors.request.use(apiRequestLockInterceptor);
export instance;
创建APILockService,该APILockService将管理Loacking,解锁和等待API
class APILockService {
constructor() {
this.locked = false
this.lockToken = null;
}
lock = (lockToken) => {
if(this.locked){
throw new Error('APIService has already been locked.');
}
this.lockToken = lockToken;
this.locked = true;
}
isLocked = (config) => {
if(config.lockToken === this.lockToken){ //We do not want to block the API request which placed the lock in first place
return false;
}
return this.locked;
}
releaseLock = (lockToken,resolve) => {
if(lockToken === this.lockToken){
this.locked = false;
if(typeof this.resolveWaitPromise === 'function') {
this.resolveWaitPromise();
}
}
}
waitTillUnlocked = () => {
return new Promise((resolve,reject) => {
this.resolveWaitPromise = () => {
resolve();
}
setTimeout(() =>{
this.locked = false;
resolve();
},300000);// timeout after 5 mins
});
}
}
const apiServiceInstance = new APILockService();
export default apiServiceInstance;
锁令牌是一种识别放置锁的API调用的方法。我们不想阻止此API。
我们使用APILockService这样的东西
function getAppToken() {
const lockToken = new Date().toISOString();
const options = {
method: ‘get’,headers: { ‘content-type’: ‘application/x-www-form-urlencoded’},data: qs.stringify(data),url: ‘/app/token?userId=123’,lockToken
};
APILockService.lock(lockToken);
return axios(options)
.then(response => {
APILockService.releaseLock(lockToken);
return response.token
});
}