Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
September 25, 2021 12:45 pm GMT

Synchronized executions in Javascript

Actually, I'm not really sure about the title of this blog because currently, I can't come up with any better title to describe what I want to share with you guys today. I don't know if it's called something else, if anyone knows, please point it out, I very much appreciate it.

Okay, so first let's start with our use case:

We have 2 functions, let's call them A and B. We call them at the same time, but we want B to wait for A to finish first.

I have a really simple function like this:

(async () => {    const sub = {        name: "sub",        subscribed: false,    };    // 1.subscribe function    const subscribe = () => {        setTimeout(() => {            sub.subscribed = true;        }, [9.5 * 1000]); // execute after 9.5 seconds    };    // 2. a function only happen after subscribed    const afterSubscribed = () => {        if (sub.subscribed) {            console.log("subscribed");        } else {            console.log("Not subscribed");        }    };    subscribe();    afterSubscribed();})();

And the output of this function would be:

// immediatelyNot subscribed// Continue to run 9.5 seconds then stop

The result I want is that this function somehow prints out "Subscribed".

Let's try to solve it.

The first try we can do is that we can create an interval in the afterSubscribed function like this, note that we will add a timer to see when we get right log:

// 2. a function only happen after subscribed    const afterSubscribed = async () => {        const start = Date.now();        const interval = setInterval(() => {            if (sub.subscribed) {                console.log("subscribed");                const end = Date.now();                const duration = Math.floor(end - start);                console.log(`on: ${duration}`);                clearInterval(interval);            } else {                console.log("Not subscribed");            }        }, [1000]);    };

Now we will retrieve the result we want:

// This is the log of this functionNot subscribedNot subscribedNot subscribedNot subscribedNot subscribedNot subscribedNot subscribedNot subscribedNot subscribedsubscribedon: 10011

Yeah, it prints out the result we want, it's quite good. The issue of this approach is that we only check for the state of the sub every 1 second. So in case, our subscribe function finishes after 9.1, 9.2... seconds, we still have to wait until the 10th second. But it's still acceptable as long as we don't need afterSubscribed to continue to execute right after subscribe finished.

To resolve the issue of the #1 try, we can change our functions like this:

(async () => {    const sub = {        name: "sub",        subscribed: false,        doneSubscribed: false,        processSubscribe: false,    };    // 1.subscribe function    const subscribe = () => {        sub.processSubscribe = new Promise(            (resolve) => (sub.doneSubscribed = resolve)        );        setTimeout(() => {            sub.subscribed = true;            sub.doneSubscribed();        }, [9.5 * 1000]); // execute after 10 seconds    };    // 2. a function only happen after subscribed    const afterSubscribed = async () => {        const start = Date.now();        await sub.processSubscribe;        if (sub.subscribed) {            console.log("subscribed");        } else {            console.log("Not subscribed");        }        const end = Date.now();        const duration = Math.floor(end - start);        console.log(`on: ${duration}`);    };    subscribe();    afterSubscribed();})();

And this is what we get:

// Wait for 9.5 second then..subscribedon: 9507

Okay, so no more "Not subscribed" and right after subscribe finished its works

Let me explain how it works.

We add 2 more attributes to sub :

doneSubscribed: false,processSubscribe: false,

And in subscribe function, we assign sub.processSubscribe to a promise where resolve function is assigned to sub.doneSubscribe. In setTimeout, we call sub.doneSubscribe function (since we assigned it to the resolve function of sub.processSubscribe promise, it's a function now). The trick here is that we assign the resolve function of sub.processSubscribe to sub.doneSubscribe, we all know that the promise resolves when its resolve/reject function is called. By awaiting for sub.processSubscribe we also wait for setTimeout to finish as well as subscribe function.

Of course, there might be some other way to solve this problem, but I think this one is one of the shortest and best ways to solve it.

So in general, this problem can be described as "wait for an executing function to finish before executing another function".

If you guys have any other ways to solve it. Feel free to share with me. Or If I did any mistake, please point it out, I really appreciate it. Thank for reading


Original Link: https://dev.to/trunghieu99tt/synchronized-executions-in-javascript-9bf

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To