Моему клиентскому приложению Javascript требуется определенная структура данных со стороны сервера ("списки"). Несколько разных мест в приложении требуют доступа к спискам. При запуске все эти места делают запрос, что приводит к нескольким одновременным запросам к серверу для одной и той же структуры данных.
Я хотел бы выполнить только один запрос к серверу, и все запрашивающие просто получают обещание, которое разрешается, когда запрос возвращается.
Я думаю, что метод заключается в создании массива или стека обещаний. Если первый запрос выполняется, то каждый последующий запрос создает обещание, которое создается и добавляется в стек. Когда ответ возвращается, система проходит через стек и разрешает все обещания с результатом.
Проблема в том, что я не могу понять правильный синтаксис, чтобы заставить это работать. Это то, что у меня пока есть:
let lists = [];
let loading = false;
let promises = [];
function getLists() {
if (lists.length > 0) {
// return cached copy
return Promise.resolve(lists);
}
/*
This method can get called several times in quick succession on startup.
To prevent sending multiple requests to the server, we maintain
a stack of promises. If there is already a request in-flight, then just
add a promise to the stack and return it. Then resolve all promises
in the stack when the request returns.
*/
let prom = new Promise(); // BAD, NOT ALLOWED
promises.push(prom);
if (!loading) {
callListsApi(); // async call, resolves promises
}
return prom;
}
function callListsApi() {
loading = true;
axios.get("/lists").then(
response => {
loading = false;
if (!response.data || response.data.length == 0) {
lists = [];
} else {
lists = response.data;
}
for (let i = 0; i < promises.length; i++) {
promises[i].resolve(lists); // give all the callers their lists
}
promises = [];
},
error => {
loading = false;
util.handleAxiosError(error);
let msg = util.getAxiosErrorText(error);
for (let i = 0; i < promises.length; i++) {
promises[i].reject(msg);
}
promises = [];
}
);
}
Это не работает, потому что вы не можете создать голый Promise (), не вставив в него какую-то функцию-исполнитель.
Как мне переписать это, чтобы оно работало?