mirror of
https://github.com/arthurfiorette/axios-cache-interceptor.git
synced 2025-12-08 17:36:16 +00:00
fix: concurrent requests not beeing cached
This commit is contained in:
parent
6e61c0d5db
commit
1490bfc30b
4
.vscode/launch.json
vendored
4
.vscode/launch.json
vendored
@ -10,7 +10,9 @@
|
||||
"${workspaceRoot}/node_modules/jest/bin/jest.js",
|
||||
// Linux:
|
||||
// "${workspaceRoot}/node_modules/.bin/jest",
|
||||
"--runInBand"
|
||||
"--runInBand",
|
||||
"--watch",
|
||||
"request.test.ts"
|
||||
],
|
||||
"console": "integratedTerminal",
|
||||
"internalConsoleOptions": "neverOpen",
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { AxiosCacheInstance, CacheRequestConfig } from '../axios/types';
|
||||
import { CachedResponse } from '../storage/types';
|
||||
import { CachedResponse, CachedStorageValue, LoadingStorageValue } from '../storage/types';
|
||||
import { Deferred } from '../util/deferred';
|
||||
import { CACHED_STATUS_CODE, CACHED_STATUS_TEXT } from '../util/status-codes';
|
||||
import { AxiosInterceptor } from './types';
|
||||
@ -27,10 +27,19 @@ export class CacheRequestInterceptor implements AxiosInterceptor<CacheRequestCon
|
||||
const key = this.axios.generateKey(config);
|
||||
|
||||
// Assumes that the storage handled staled responses
|
||||
const cache = await this.axios.storage.get(key);
|
||||
let cache = await this.axios.storage.get(key);
|
||||
|
||||
// Not cached, continue the request, and mark it as fetching
|
||||
if (cache.state == 'empty') {
|
||||
emptyState: if (cache.state == 'empty') {
|
||||
// This if catches concurrent access to a new key.
|
||||
// The js event loop skips in the first await statement,
|
||||
// so the next code block will be executed both if called
|
||||
// from two places asynchronously.
|
||||
if (this.axios.waiting[key]) {
|
||||
cache = (await this.axios.storage.get(key)) as CachedStorageValue | LoadingStorageValue;
|
||||
break emptyState;
|
||||
}
|
||||
|
||||
// Create a deferred to resolve other requests for the same key when it's completed
|
||||
this.axios.waiting[key] = new Deferred();
|
||||
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import { mockAxios } from '../mocks/axios';
|
||||
import { StatusCodes } from '../../src';
|
||||
import { axiosMock, mockAxios } from '../mocks/axios';
|
||||
|
||||
describe('test request interceptor', () => {
|
||||
it('tests against specified methods', async () => {
|
||||
@ -26,4 +27,15 @@ describe('test request interceptor', () => {
|
||||
|
||||
expect(cache.state).toBe('cached');
|
||||
});
|
||||
|
||||
it('tests concurrent requests', async () => {
|
||||
const axios = mockAxios();
|
||||
|
||||
const [resp1, resp2] = await Promise.all([axios.get(''), axios.get('')]);
|
||||
|
||||
expect(resp1).toHaveProperty('status', axiosMock.statusCode);
|
||||
expect(resp1).toHaveProperty('statusText', axiosMock.statusText);
|
||||
expect(resp2).toHaveProperty('status', StatusCodes.CACHED_STATUS_CODE);
|
||||
expect(resp2).toHaveProperty('statusText', StatusCodes.CACHED_STATUS_TEXT);
|
||||
});
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user