Во-первых, мы создаем ax ios instance
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, который будет управлять блокировкой, разблокировкой и ожиданием 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
});
}