Разрешение ожидающих параллельных промисов

Недавно я обновил установку HAPI до версии 17, в которой используются промисы, и столкнулся с ситуацией, которую не знаю, как решить. Это не специфично для HAPI...

Когда вызывается определенный маршрут, выполняется проверка, были ли результаты вызова конкретной службы кэшированы. Если это так, мы пропускаем вызов и используем кэшированные результаты — в противном случае выполняется вызов службы, который включает в себя обещание.

Проблема в том, что если сервер запущен, а результаты не кэшированы, и мы запускаем нагрузочный тест, вдруг возникает поток обращений к службе для получения результатов, потому что они еще не были кэшированы, и куча запросов просто пришла одновременно.

Что я хочу сделать, так это позволить первому запросу запустить сервисный вызов и просто позволить всем последующим запросам ждать (через обещание?) для возврата этого вызова - тогда все ожидающие обещания могут быть разрешены, чтобы другие запросы продолжались.

Как мне это структурировать? В прошлом, используя обратные вызовы, я просто добавлял обратные вызовы в список, а затем вызывал все обратные вызовы в этом списке после получения результатов. Могу ли я как-то сделать что-то подобное, но складывать обещания до тех пор, пока вызов не вернется, а затем решить торговый центр? Я все еще новичок в обещаниях, поэтому мне трудно это визуализировать.

Базовая упрощенная логика, используемая в настоящее время, такова:

function getData() {
    return new Promise(...);
}

...

if (!data) {
    data = await getData();
}
return data;

Вместо того, чтобы просто вызывать getData(), если данные не кэшированы, я хочу установить флаг, когда getData отправляет запрос на его получение, и чтобы последующие вызовы ждали завершения этого запроса, чтобы получить данные и двигаться дальше, а не отправлять еще другой запрос на это.

Спасибо!

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
0
49
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете кэшировать само обещание вместо кэширования данных + флаг, чтобы увидеть, получены ли данные.

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 — она получит старые данные из предыдущего промиса. Но по вашему описанию не ваше дело подменять обещание, пока оно не выполнено, не так ли?

Другие вопросы по теме