@olezhenka

Как заставить все запросы ждать один промис?

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

// внутри async function
chat.quiz = global_quizzes[quiz_id];
if(!chat.quiz) {
    // проблема в дубли
    chat.quiz = await Chat_Quizzes.findById(quiz_id).exec();
    global_quizzes[quiz_id] = chat.quiz;
}
  • Вопрос задан
  • 151 просмотр
Решения вопроса 2
MvcBox
@MvcBox
Back-end developer
Можете использовать очередь

Пример:
'use strict';

const { Queue } = require('plain-queue');
const queue = new Queue;

// внутри async function
    chat.quiz = global_quizzes[quiz_id];
    
    if(!chat.quiz) {
        chat.quiz = await queue.addTask(function () {
            return global_quizzes[quiz_id] || Chat_Quizzes.findById(quiz_id).exec();
        });

        global_quizzes[quiz_id] = chat.quiz;
    }
Ответ написан
lastuniverse
@lastuniverse
Всегда вокруг да около IT тем
Как подсказал Inviz Custos, очередь решит вашу проблему (если конечно правильно будет работать с дублирующими запросами и промисами)

Вот простенький рабочий пример
// внутри async function
let quiz = global_quizzes[quiz_id];
if(!quiz) {
    global_quizzes[quiz_id] = quiz = Chat_Quizzes.findById(quiz_id).exec();
}

if( quiz instanceof Promise ){
    global_quizzes[quiz_id] = quiz = await quiz;
} 
chat.quiz = quiz;


PS: правда это не совсем очередь, но ваш global_quizzes в некоторой степени ее имитирует.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы