Справочная информация: Браузеры ограничивают количество одновременных запросов. Например, Chrome имеет ограничение в 6 подключений на имя хоста и максимум 10 подключений.
// Redux actions:
import axios from 'axios';
const LIMIT = 6;
const populateQueue = (requestConfigs) => ({ type: 'POPULATE_QUEUE', payload: requestConfigs });
const popRequest = () => ({ type: 'POP_REQUEST' });
export const initializeQueue = (requestConfigs) => (dispatch) => {
// Grab as many request as we allow to run concurrently
const initialRequests = requestConfigs.slice(0, LIMIT);
// Put the rest in a queue
const remainingRequests = requestConfigs.slice(LIMIT, requestConfigs.length);
dispatch(populateQueue(remainingRequests));
// Start the first batch. When one of requests finishes,
// it will pop the next from the queue and start it.
initialRequests.forEach((requestConfig) => dispatch(startRequest(requestConfig)));
};
const startRequest = (requestConfig) => async (dispatch, getState) => {
try {
await axios(requestConfig);
// process response here
} catch(error) {
// error handling
} finally {
const { queue } = getState().queuedRequests;
if (queue.length) {
// Queue not empty yet, start the next request
const next = queue[0];
dispatch(popRequest());
dispatch(startRequest(next));
}
}
};
// Reducer:
const initialState = {
queue: []
};
const queuedRequestReducer = (state = initialState, action) => {
if (action.type === 'POPULATE_QUEUE') {
return { queue: action.payload };
} else if (action.type === 'POP_REQUEST') {
return { queue: state.queue.slice(1, state.queue.length) };
}
return state;
};
export default queuedRequestReducer;
// In the React component this would be triggered with:
<button onClick={() => initializeQueue(requestConfigs)}>fetch a lot of data</button>