E
E
everpi2018-12-25 21:43:53
JavaScript
everpi, 2018-12-25 21:43:53

How would the event loop work in this situation?

Hello. What if the code gets to await.fetch() and at that moment the interval fires and deletes the array we are going to push data into after the asynchronous operation, we get '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);

Will wrapping the callback in setImmediate() fix this problem and is it a good solution to this problem?
Actually the example is bad and doesn't reflect my problem. It is necessary for me that when one function manipulates over object others did not interfere with it. setImmediate would be fine (as I understand it, it puts the execution of the callback before the interval), but when asynchronous functions are called in on('message') , the execution flow is transferred to the interval and everything is a mess :)

Answer the question

In order to leave comments, you need to log in

3 answer(s)
E
everpi, 2018-12-27
@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;
    }
};

A
Alexey, 2018-12-25
@alekstar79

As a matter of fact, it may not delete the array at all, but, as in the request, set it to empty.

if (Date.now() > session.date) {
    session.isRedirect = false;
    session.unanswered = [];
}

... no, it won't?

M
Marat Garifullin, 2018-12-25
@magarif

Perhaps something like this

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);

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question