About random result of a snippet of event loop code





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







2















I'm studying about javascript event loop, and I tried some complex and nested async codes, and one of them complicated me so much. The code snippet looks like:



console.log(1);
new Promise((resolve, reject) => {
console.log(2);
resolve();
}).then(() => {
setTimeout(() => { console.log(3) }, 0);
});
setTimeout(() => {
new Promise((resolve, reject) => {
console.log(4);
resolve();
}).then(() => { console.log(5) });
});


And the result sometimes is 1 - 2 - 4 - 5 - 3, and sometimes is 1 - 2 - 4 - 3- 5.



It performs the same in browser environment and node environment.



Maybe my code is written wrong, or there are some issues exist in V8 resolving event loop?










share|improve this question

























  • The timeout functions are part of Web APIs in the browser. They are put into the message queue and are executed when the call stack is empty. They aren't time deterministic as far as I know.

    – theapologist
    Nov 22 '18 at 11:20











  • settimeout guarantees the least time wait but does not guarantee the exact wait time. So, if you are dealing with multiple timeout, it is more likely than they have to wait more than their set time. Because even after the times ends, they also have to wait for the call stacks to be empty.

    – b1k
    Nov 22 '18 at 13:01


















2















I'm studying about javascript event loop, and I tried some complex and nested async codes, and one of them complicated me so much. The code snippet looks like:



console.log(1);
new Promise((resolve, reject) => {
console.log(2);
resolve();
}).then(() => {
setTimeout(() => { console.log(3) }, 0);
});
setTimeout(() => {
new Promise((resolve, reject) => {
console.log(4);
resolve();
}).then(() => { console.log(5) });
});


And the result sometimes is 1 - 2 - 4 - 5 - 3, and sometimes is 1 - 2 - 4 - 3- 5.



It performs the same in browser environment and node environment.



Maybe my code is written wrong, or there are some issues exist in V8 resolving event loop?










share|improve this question

























  • The timeout functions are part of Web APIs in the browser. They are put into the message queue and are executed when the call stack is empty. They aren't time deterministic as far as I know.

    – theapologist
    Nov 22 '18 at 11:20











  • settimeout guarantees the least time wait but does not guarantee the exact wait time. So, if you are dealing with multiple timeout, it is more likely than they have to wait more than their set time. Because even after the times ends, they also have to wait for the call stacks to be empty.

    – b1k
    Nov 22 '18 at 13:01














2












2








2








I'm studying about javascript event loop, and I tried some complex and nested async codes, and one of them complicated me so much. The code snippet looks like:



console.log(1);
new Promise((resolve, reject) => {
console.log(2);
resolve();
}).then(() => {
setTimeout(() => { console.log(3) }, 0);
});
setTimeout(() => {
new Promise((resolve, reject) => {
console.log(4);
resolve();
}).then(() => { console.log(5) });
});


And the result sometimes is 1 - 2 - 4 - 5 - 3, and sometimes is 1 - 2 - 4 - 3- 5.



It performs the same in browser environment and node environment.



Maybe my code is written wrong, or there are some issues exist in V8 resolving event loop?










share|improve this question
















I'm studying about javascript event loop, and I tried some complex and nested async codes, and one of them complicated me so much. The code snippet looks like:



console.log(1);
new Promise((resolve, reject) => {
console.log(2);
resolve();
}).then(() => {
setTimeout(() => { console.log(3) }, 0);
});
setTimeout(() => {
new Promise((resolve, reject) => {
console.log(4);
resolve();
}).then(() => { console.log(5) });
});


And the result sometimes is 1 - 2 - 4 - 5 - 3, and sometimes is 1 - 2 - 4 - 3- 5.



It performs the same in browser environment and node environment.



Maybe my code is written wrong, or there are some issues exist in V8 resolving event loop?







javascript event-loop






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 22 '18 at 13:58







lujuemin

















asked Nov 22 '18 at 6:30









lujueminlujuemin

113




113













  • The timeout functions are part of Web APIs in the browser. They are put into the message queue and are executed when the call stack is empty. They aren't time deterministic as far as I know.

    – theapologist
    Nov 22 '18 at 11:20











  • settimeout guarantees the least time wait but does not guarantee the exact wait time. So, if you are dealing with multiple timeout, it is more likely than they have to wait more than their set time. Because even after the times ends, they also have to wait for the call stacks to be empty.

    – b1k
    Nov 22 '18 at 13:01



















  • The timeout functions are part of Web APIs in the browser. They are put into the message queue and are executed when the call stack is empty. They aren't time deterministic as far as I know.

    – theapologist
    Nov 22 '18 at 11:20











  • settimeout guarantees the least time wait but does not guarantee the exact wait time. So, if you are dealing with multiple timeout, it is more likely than they have to wait more than their set time. Because even after the times ends, they also have to wait for the call stacks to be empty.

    – b1k
    Nov 22 '18 at 13:01

















The timeout functions are part of Web APIs in the browser. They are put into the message queue and are executed when the call stack is empty. They aren't time deterministic as far as I know.

– theapologist
Nov 22 '18 at 11:20





The timeout functions are part of Web APIs in the browser. They are put into the message queue and are executed when the call stack is empty. They aren't time deterministic as far as I know.

– theapologist
Nov 22 '18 at 11:20













settimeout guarantees the least time wait but does not guarantee the exact wait time. So, if you are dealing with multiple timeout, it is more likely than they have to wait more than their set time. Because even after the times ends, they also have to wait for the call stacks to be empty.

– b1k
Nov 22 '18 at 13:01





settimeout guarantees the least time wait but does not guarantee the exact wait time. So, if you are dealing with multiple timeout, it is more likely than they have to wait more than their set time. Because even after the times ends, they also have to wait for the call stacks to be empty.

– b1k
Nov 22 '18 at 13:01












2 Answers
2






active

oldest

votes


















0














Callback execution order is not really deterministic. Whenever a Promise resolves, a task that executes the .then() chain gets pushed onto the Eventqueue. The same happens when a timer resolves. As timers run concurrently, they might not finish exactly in the order they were started, if they are close to each other.



  main code executes (1) {
promise (2) gets pushed onto the queue
promise (4) gets pushed onto the queue
}


promise resolves (2) {
a 0ms timer gets set (3)
}

// maybe the timer is done already (3)

promise resolves(4)

// maybe the timer is done now (3)





share|improve this answer


























  • How does the timer apply to (5)? Is this how it always work whenever we have Promise inside settimeout?

    – b1k
    Nov 22 '18 at 7:18











  • @b1k no, I mixed up the example a bit, apologies ...

    – Jonas Wilms
    Nov 22 '18 at 11:15



















0














You are combining two things: Promise.resolve and window.setTimeout. The former runs synchronously and places the resolved item in the queue immediately. The window.setTimeout however has a different approach. It start to handle the provided function once the timer has expired. When using 0 as delay in window.setTimeout as you have used in your first promise:



setTimeout(() => { console.log(3) }, 0);


then it does not mean "run this immediately". It is more "run this function as soon as possible". That can be changed because the timer is being throttled by browsers. If you do not have problems to read some specs, you can read timer-initialisation-steps to comprehend how it is being initialized in detail.



There is a more easier-to-read information on MDN: Reasons for delays longer than specified



Dependent of the browser/engine, the engine might be busy with (background) tasks so that timers gets throttled. As you have experienced yourself, there is a situation where you are getting different results. The minimum throttling time is (according to the specs, but browsers can use a different value) 4ms. The end result is that the function in the throttled timer gets executed after the another timer that did not got throttled.






share|improve this answer
























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53425066%2fabout-random-result-of-a-snippet-of-event-loop-code%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    Callback execution order is not really deterministic. Whenever a Promise resolves, a task that executes the .then() chain gets pushed onto the Eventqueue. The same happens when a timer resolves. As timers run concurrently, they might not finish exactly in the order they were started, if they are close to each other.



      main code executes (1) {
    promise (2) gets pushed onto the queue
    promise (4) gets pushed onto the queue
    }


    promise resolves (2) {
    a 0ms timer gets set (3)
    }

    // maybe the timer is done already (3)

    promise resolves(4)

    // maybe the timer is done now (3)





    share|improve this answer


























    • How does the timer apply to (5)? Is this how it always work whenever we have Promise inside settimeout?

      – b1k
      Nov 22 '18 at 7:18











    • @b1k no, I mixed up the example a bit, apologies ...

      – Jonas Wilms
      Nov 22 '18 at 11:15
















    0














    Callback execution order is not really deterministic. Whenever a Promise resolves, a task that executes the .then() chain gets pushed onto the Eventqueue. The same happens when a timer resolves. As timers run concurrently, they might not finish exactly in the order they were started, if they are close to each other.



      main code executes (1) {
    promise (2) gets pushed onto the queue
    promise (4) gets pushed onto the queue
    }


    promise resolves (2) {
    a 0ms timer gets set (3)
    }

    // maybe the timer is done already (3)

    promise resolves(4)

    // maybe the timer is done now (3)





    share|improve this answer


























    • How does the timer apply to (5)? Is this how it always work whenever we have Promise inside settimeout?

      – b1k
      Nov 22 '18 at 7:18











    • @b1k no, I mixed up the example a bit, apologies ...

      – Jonas Wilms
      Nov 22 '18 at 11:15














    0












    0








    0







    Callback execution order is not really deterministic. Whenever a Promise resolves, a task that executes the .then() chain gets pushed onto the Eventqueue. The same happens when a timer resolves. As timers run concurrently, they might not finish exactly in the order they were started, if they are close to each other.



      main code executes (1) {
    promise (2) gets pushed onto the queue
    promise (4) gets pushed onto the queue
    }


    promise resolves (2) {
    a 0ms timer gets set (3)
    }

    // maybe the timer is done already (3)

    promise resolves(4)

    // maybe the timer is done now (3)





    share|improve this answer















    Callback execution order is not really deterministic. Whenever a Promise resolves, a task that executes the .then() chain gets pushed onto the Eventqueue. The same happens when a timer resolves. As timers run concurrently, they might not finish exactly in the order they were started, if they are close to each other.



      main code executes (1) {
    promise (2) gets pushed onto the queue
    promise (4) gets pushed onto the queue
    }


    promise resolves (2) {
    a 0ms timer gets set (3)
    }

    // maybe the timer is done already (3)

    promise resolves(4)

    // maybe the timer is done now (3)






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Nov 22 '18 at 11:14

























    answered Nov 22 '18 at 6:44









    Jonas WilmsJonas Wilms

    66k53660




    66k53660













    • How does the timer apply to (5)? Is this how it always work whenever we have Promise inside settimeout?

      – b1k
      Nov 22 '18 at 7:18











    • @b1k no, I mixed up the example a bit, apologies ...

      – Jonas Wilms
      Nov 22 '18 at 11:15



















    • How does the timer apply to (5)? Is this how it always work whenever we have Promise inside settimeout?

      – b1k
      Nov 22 '18 at 7:18











    • @b1k no, I mixed up the example a bit, apologies ...

      – Jonas Wilms
      Nov 22 '18 at 11:15

















    How does the timer apply to (5)? Is this how it always work whenever we have Promise inside settimeout?

    – b1k
    Nov 22 '18 at 7:18





    How does the timer apply to (5)? Is this how it always work whenever we have Promise inside settimeout?

    – b1k
    Nov 22 '18 at 7:18













    @b1k no, I mixed up the example a bit, apologies ...

    – Jonas Wilms
    Nov 22 '18 at 11:15





    @b1k no, I mixed up the example a bit, apologies ...

    – Jonas Wilms
    Nov 22 '18 at 11:15













    0














    You are combining two things: Promise.resolve and window.setTimeout. The former runs synchronously and places the resolved item in the queue immediately. The window.setTimeout however has a different approach. It start to handle the provided function once the timer has expired. When using 0 as delay in window.setTimeout as you have used in your first promise:



    setTimeout(() => { console.log(3) }, 0);


    then it does not mean "run this immediately". It is more "run this function as soon as possible". That can be changed because the timer is being throttled by browsers. If you do not have problems to read some specs, you can read timer-initialisation-steps to comprehend how it is being initialized in detail.



    There is a more easier-to-read information on MDN: Reasons for delays longer than specified



    Dependent of the browser/engine, the engine might be busy with (background) tasks so that timers gets throttled. As you have experienced yourself, there is a situation where you are getting different results. The minimum throttling time is (according to the specs, but browsers can use a different value) 4ms. The end result is that the function in the throttled timer gets executed after the another timer that did not got throttled.






    share|improve this answer




























      0














      You are combining two things: Promise.resolve and window.setTimeout. The former runs synchronously and places the resolved item in the queue immediately. The window.setTimeout however has a different approach. It start to handle the provided function once the timer has expired. When using 0 as delay in window.setTimeout as you have used in your first promise:



      setTimeout(() => { console.log(3) }, 0);


      then it does not mean "run this immediately". It is more "run this function as soon as possible". That can be changed because the timer is being throttled by browsers. If you do not have problems to read some specs, you can read timer-initialisation-steps to comprehend how it is being initialized in detail.



      There is a more easier-to-read information on MDN: Reasons for delays longer than specified



      Dependent of the browser/engine, the engine might be busy with (background) tasks so that timers gets throttled. As you have experienced yourself, there is a situation where you are getting different results. The minimum throttling time is (according to the specs, but browsers can use a different value) 4ms. The end result is that the function in the throttled timer gets executed after the another timer that did not got throttled.






      share|improve this answer


























        0












        0








        0







        You are combining two things: Promise.resolve and window.setTimeout. The former runs synchronously and places the resolved item in the queue immediately. The window.setTimeout however has a different approach. It start to handle the provided function once the timer has expired. When using 0 as delay in window.setTimeout as you have used in your first promise:



        setTimeout(() => { console.log(3) }, 0);


        then it does not mean "run this immediately". It is more "run this function as soon as possible". That can be changed because the timer is being throttled by browsers. If you do not have problems to read some specs, you can read timer-initialisation-steps to comprehend how it is being initialized in detail.



        There is a more easier-to-read information on MDN: Reasons for delays longer than specified



        Dependent of the browser/engine, the engine might be busy with (background) tasks so that timers gets throttled. As you have experienced yourself, there is a situation where you are getting different results. The minimum throttling time is (according to the specs, but browsers can use a different value) 4ms. The end result is that the function in the throttled timer gets executed after the another timer that did not got throttled.






        share|improve this answer













        You are combining two things: Promise.resolve and window.setTimeout. The former runs synchronously and places the resolved item in the queue immediately. The window.setTimeout however has a different approach. It start to handle the provided function once the timer has expired. When using 0 as delay in window.setTimeout as you have used in your first promise:



        setTimeout(() => { console.log(3) }, 0);


        then it does not mean "run this immediately". It is more "run this function as soon as possible". That can be changed because the timer is being throttled by browsers. If you do not have problems to read some specs, you can read timer-initialisation-steps to comprehend how it is being initialized in detail.



        There is a more easier-to-read information on MDN: Reasons for delays longer than specified



        Dependent of the browser/engine, the engine might be busy with (background) tasks so that timers gets throttled. As you have experienced yourself, there is a situation where you are getting different results. The minimum throttling time is (according to the specs, but browsers can use a different value) 4ms. The end result is that the function in the throttled timer gets executed after the another timer that did not got throttled.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 22 '18 at 14:37









        KarelGKarelG

        4,08932545




        4,08932545






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53425066%2fabout-random-result-of-a-snippet-of-event-loop-code%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Guess what letter conforming each word

            Port of Spain

            Run scheduled task as local user group (not BUILTIN)