@everpi

Как сработает цикл событий в данной ситуации?

Здравствуйте. Что если код дойдет до await.fetch() и в этот момент сработает интервал и удалит массив, в который мы собираемся пушить данные после асинхронной операции, мы получим 'Cannot read property 'push' of undefined'?)

const session = {
    unanswered: [],
    isRedirect: true,
    date: 1545762010253
};

client.on('message', async (msg) => {
    if (session.isRedirect) {
        await fetch(...);
        session.unanswered.push(msg.id);
    } else {
        session.isRedirect = true;
        session.unanswered = [];
        session.date = Date.now() + 60 * 1000;
    }
});

setInterval(() => {
    if (Date.now() > session.date) {
        session.isRedirect = false;
        delete session.unanswered;
    }
}, 100);


Исправит ли эту проблему заворачивание коллбека в setImmediate() и будет ли это хорошим решением данной проблемы?

На самом деле пример плохой и не отражает моей проблемы. Мне нужно чтобы когда одна функцию манипулирует над объектом ей не мешали другие. setImmediate бы подошел (он как я понял ставит исполнение коллбека перед интервалом), но когда в on('message') вызываются асинхронные функции поток выполнения передается интервалу и все в кашу :)
  • Вопрос задан
  • 370 просмотров
Решения вопроса 1
@everpi Автор вопроса
const delay = ms => new Promise(res => setTimeout(res, ms));

const doAfterUnlock = async (session, func, ...args) => {
    while (session.isBlock) {
        // eslint-disable-next-line no-await-in-loop
        await delay(1); // free event loop
    }

    try {
        session.isBlock = true;
        await func(...args);
    } catch (e) {
        console.error(e);
    } finally {
        session.isBlock = false;
    }
};
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
alekstar79
@alekstar79
Собственно говоря может не удалять массив вовсе, а как и в запросе, устанавливать пустым.
if (Date.now() > session.date) {
    session.isRedirect = false;
    session.unanswered = [];
}

...нет, не пойдет?
Ответ написан
@magarif
Программист
Возможно что-то такое

const session = {
    unanswered: [],
    isRedirect: true,
    date: 1545762010253
};
const intervalID = null;
const checkSession = () => {
    if (Date.now() > session.date) {
        session.isRedirect = false;
        delete session.unanswered;
    }
};

client.on('message', async (msg) => {
    if (session.isRedirect) {
        сlearInterval(intervalID);
        await fetch(...);
        session.unanswered.push(msg.id);
        intervalID = setInterval(checkSession, 100);
    } else {
        session.isRedirect = true;
        session.unanswered = [];
        session.date = Date.now() + 60 * 1000;
    }
});

intervalID = setInterval(checkSession, 100);
Ответ написан
Ваш ответ на вопрос

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

Похожие вопросы