Разрешение ожидающих параллельных обещаний - PullRequest
0 голосов
/ 22 февраля 2019

Я недавно обновил установку HAPI до версии 17, в которой используются обещания, и столкнулся с ситуацией, которую я не знаю, как решить.Это не зависит от HAPI ...

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

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

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

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

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

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

...

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

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

Спасибо!

1 Ответ

0 голосов
/ 22 февраля 2019

Вы можете кэшировать само обещание вместо кэширования данных + flag-to-see-if-data-retrieved.

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

...