Недавно я обновил установку HAPI до версии 17, в которой используются промисы, и столкнулся с ситуацией, которую не знаю, как решить. Это не специфично для HAPI...
Когда вызывается определенный маршрут, выполняется проверка, были ли результаты вызова конкретной службы кэшированы. Если это так, мы пропускаем вызов и используем кэшированные результаты — в противном случае выполняется вызов службы, который включает в себя обещание.
Проблема в том, что если сервер запущен, а результаты не кэшированы, и мы запускаем нагрузочный тест, вдруг возникает поток обращений к службе для получения результатов, потому что они еще не были кэшированы, и куча запросов просто пришла одновременно.
Что я хочу сделать, так это позволить первому запросу запустить сервисный вызов и просто позволить всем последующим запросам ждать (через обещание?) для возврата этого вызова - тогда все ожидающие обещания могут быть разрешены, чтобы другие запросы продолжались.
Как мне это структурировать? В прошлом, используя обратные вызовы, я просто добавлял обратные вызовы в список, а затем вызывал все обратные вызовы в этом списке после получения результатов. Могу ли я как-то сделать что-то подобное, но складывать обещания до тех пор, пока вызов не вернется, а затем решить торговый центр? Я все еще новичок в обещаниях, поэтому мне трудно это визуализировать.
Базовая упрощенная логика, используемая в настоящее время, такова:
function getData() {
return new Promise(...);
}
...
if (!data) {
data = await getData();
}
return data;
Вместо того, чтобы просто вызывать getData(), если данные не кэшированы, я хочу установить флаг, когда getData отправляет запрос на его получение, и чтобы последующие вызовы ждали завершения этого запроса, чтобы получить данные и двигаться дальше, а не отправлять еще другой запрос на это.
Спасибо!



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вы можете кэшировать само обещание вместо кэширования данных + флаг, чтобы увидеть, получены ли данные.
function loadData() {
someOuterVariable = fetch(...).then(/*transforming data structure*/)
}
async function dataConsumer() {
const data = await someOuterVariable; // does not matter if it has been retrieved or not
....
}
async function anotherConsumer() {
....
const item = (await someOuterVariable).filter(/* just an example of inline processing*/)
}
И неважно, были уже получены данные или нет — Promise остается Promise.
Единственное ограничение — вы можете обновить этот someOuterVariable новым промисом, но если какая-либо потребительская функция уже начала await — она получит старые данные из предыдущего промиса. Но по вашему описанию не ваше дело подменять обещание, пока оно не выполнено, не так ли?