Helper function to make `setTimeout` synchronous





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ margin-bottom:0;
}







2












$begingroup$


I'm making a helper function to make setTimeout synchronous. Currently, it is asynchronous so other code runs before the timeout is done.



function syncSetTimeout(func, ms, callback) {
(function sync(done) {
if (!done) {
setTimeout(function() {
eval("(" + func + ")();");
sync(true);
}, ms);
return;
}
eval("(" + callback + ")();");
})();
}




  • func is a function that should be run after the specified timeout.


  • ms specifies how many milliseconds to wait before running func.


  • callback is the function that runs after the func is done running.


Is there a way to get rid of those eval statements? I've read that eval is evil. I'm also wondering if I can do this without a nested function. If there are any other ways to improve this code then please say so.










share|improve this question











$endgroup$



















    2












    $begingroup$


    I'm making a helper function to make setTimeout synchronous. Currently, it is asynchronous so other code runs before the timeout is done.



    function syncSetTimeout(func, ms, callback) {
    (function sync(done) {
    if (!done) {
    setTimeout(function() {
    eval("(" + func + ")();");
    sync(true);
    }, ms);
    return;
    }
    eval("(" + callback + ")();");
    })();
    }




    • func is a function that should be run after the specified timeout.


    • ms specifies how many milliseconds to wait before running func.


    • callback is the function that runs after the func is done running.


    Is there a way to get rid of those eval statements? I've read that eval is evil. I'm also wondering if I can do this without a nested function. If there are any other ways to improve this code then please say so.










    share|improve this question











    $endgroup$















      2












      2








      2





      $begingroup$


      I'm making a helper function to make setTimeout synchronous. Currently, it is asynchronous so other code runs before the timeout is done.



      function syncSetTimeout(func, ms, callback) {
      (function sync(done) {
      if (!done) {
      setTimeout(function() {
      eval("(" + func + ")();");
      sync(true);
      }, ms);
      return;
      }
      eval("(" + callback + ")();");
      })();
      }




      • func is a function that should be run after the specified timeout.


      • ms specifies how many milliseconds to wait before running func.


      • callback is the function that runs after the func is done running.


      Is there a way to get rid of those eval statements? I've read that eval is evil. I'm also wondering if I can do this without a nested function. If there are any other ways to improve this code then please say so.










      share|improve this question











      $endgroup$




      I'm making a helper function to make setTimeout synchronous. Currently, it is asynchronous so other code runs before the timeout is done.



      function syncSetTimeout(func, ms, callback) {
      (function sync(done) {
      if (!done) {
      setTimeout(function() {
      eval("(" + func + ")();");
      sync(true);
      }, ms);
      return;
      }
      eval("(" + callback + ")();");
      })();
      }




      • func is a function that should be run after the specified timeout.


      • ms specifies how many milliseconds to wait before running func.


      • callback is the function that runs after the func is done running.


      Is there a way to get rid of those eval statements? I've read that eval is evil. I'm also wondering if I can do this without a nested function. If there are any other ways to improve this code then please say so.







      javascript






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Jul 4 '17 at 17:26









      Jamal

      30.6k11121227




      30.6k11121227










      asked Nov 14 '16 at 22:59









      ericw31415ericw31415

      11315




      11315






















          2 Answers
          2






          active

          oldest

          votes


















          3












          $begingroup$

          The Eval



          Eval is indeed, the monster. There are plenty of reasons why you should not use it, although there are some situations where you are forced to use it. For sure, this is not the requirement in yours situation. If func is a function, you can call it using .apply.



          function syncSetTimeout(func, ms, callback) {
          (function sync(done) {
          if (!done) {
          setTimeout(function() {
          func.apply(func);
          sync(true);
          }, ms);
          return;
          }
          callback.apply(callback);
          })();
          }


          Reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply



          Or event without apply:



          function syncSetTimeout(func, ms, callback) {
          (function sync(done) {
          if (!done) {
          setTimeout(function() {
          func();
          sync(true);
          }, ms);
          return;
          }
          callback();
          })();
          }


          The synchronous



          You need to know, that trying to make setTimeout() sync means that you have some very bad design idea behind. You should not do it and you will not be able to make it really sync without killing performance of the browser and UX of your app.



          I believe that you would like to create sync delay in your application. You are not the first who wants to do it (most of beginners or people with background from different language). You can take a look at answers to this question from stackoverflow: https://stackoverflow.com/questions/6921895/synchronous-delay-in-code-execution



          From the answer to linked question (by OverZealous):




          JavaScript is a single-threaded language. You cannot combine
          setTimeout and synchronous processing. What will happen is, the timer
          will lapse, but then the JS engine will wait to process the results
          until the current script completes.




          One reason people are trying to take advantage of sync delays is returning result from async code. This is not good strategy in JS. If you would like to return async results just use callbacks or more likely - Promises or Observables.






          share|improve this answer











          $endgroup$













          • $begingroup$
            I don't really understand what .apply() does. Can you explain? I've tried this page, but that's not very clear.
            $endgroup$
            – ericw31415
            Nov 14 '16 at 23:08












          • $begingroup$
            Check my updated answer.
            $endgroup$
            – rzelek
            Nov 14 '16 at 23:14










          • $begingroup$
            So are you saying that my function is flawed?
            $endgroup$
            – ericw31415
            Nov 15 '16 at 2:05



















          0












          $begingroup$

          There's a simpler solution if you are using nodejs



          {code}



          await new Promise(done => setTimeout(() => done(), 180000));


          {/code}await new Promise(done => setTimeout(() => done(), 180000));





          share








          New contributor




          Anoop George is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
          Check out our Code of Conduct.






          $endgroup$














            Your Answer





            StackExchange.ifUsing("editor", function () {
            return StackExchange.using("mathjaxEditing", function () {
            StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
            StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
            });
            });
            }, "mathjax-editing");

            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: "196"
            };
            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: false,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: null,
            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%2fcodereview.stackexchange.com%2fquestions%2f147039%2fhelper-function-to-make-settimeout-synchronous%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









            3












            $begingroup$

            The Eval



            Eval is indeed, the monster. There are plenty of reasons why you should not use it, although there are some situations where you are forced to use it. For sure, this is not the requirement in yours situation. If func is a function, you can call it using .apply.



            function syncSetTimeout(func, ms, callback) {
            (function sync(done) {
            if (!done) {
            setTimeout(function() {
            func.apply(func);
            sync(true);
            }, ms);
            return;
            }
            callback.apply(callback);
            })();
            }


            Reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply



            Or event without apply:



            function syncSetTimeout(func, ms, callback) {
            (function sync(done) {
            if (!done) {
            setTimeout(function() {
            func();
            sync(true);
            }, ms);
            return;
            }
            callback();
            })();
            }


            The synchronous



            You need to know, that trying to make setTimeout() sync means that you have some very bad design idea behind. You should not do it and you will not be able to make it really sync without killing performance of the browser and UX of your app.



            I believe that you would like to create sync delay in your application. You are not the first who wants to do it (most of beginners or people with background from different language). You can take a look at answers to this question from stackoverflow: https://stackoverflow.com/questions/6921895/synchronous-delay-in-code-execution



            From the answer to linked question (by OverZealous):




            JavaScript is a single-threaded language. You cannot combine
            setTimeout and synchronous processing. What will happen is, the timer
            will lapse, but then the JS engine will wait to process the results
            until the current script completes.




            One reason people are trying to take advantage of sync delays is returning result from async code. This is not good strategy in JS. If you would like to return async results just use callbacks or more likely - Promises or Observables.






            share|improve this answer











            $endgroup$













            • $begingroup$
              I don't really understand what .apply() does. Can you explain? I've tried this page, but that's not very clear.
              $endgroup$
              – ericw31415
              Nov 14 '16 at 23:08












            • $begingroup$
              Check my updated answer.
              $endgroup$
              – rzelek
              Nov 14 '16 at 23:14










            • $begingroup$
              So are you saying that my function is flawed?
              $endgroup$
              – ericw31415
              Nov 15 '16 at 2:05
















            3












            $begingroup$

            The Eval



            Eval is indeed, the monster. There are plenty of reasons why you should not use it, although there are some situations where you are forced to use it. For sure, this is not the requirement in yours situation. If func is a function, you can call it using .apply.



            function syncSetTimeout(func, ms, callback) {
            (function sync(done) {
            if (!done) {
            setTimeout(function() {
            func.apply(func);
            sync(true);
            }, ms);
            return;
            }
            callback.apply(callback);
            })();
            }


            Reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply



            Or event without apply:



            function syncSetTimeout(func, ms, callback) {
            (function sync(done) {
            if (!done) {
            setTimeout(function() {
            func();
            sync(true);
            }, ms);
            return;
            }
            callback();
            })();
            }


            The synchronous



            You need to know, that trying to make setTimeout() sync means that you have some very bad design idea behind. You should not do it and you will not be able to make it really sync without killing performance of the browser and UX of your app.



            I believe that you would like to create sync delay in your application. You are not the first who wants to do it (most of beginners or people with background from different language). You can take a look at answers to this question from stackoverflow: https://stackoverflow.com/questions/6921895/synchronous-delay-in-code-execution



            From the answer to linked question (by OverZealous):




            JavaScript is a single-threaded language. You cannot combine
            setTimeout and synchronous processing. What will happen is, the timer
            will lapse, but then the JS engine will wait to process the results
            until the current script completes.




            One reason people are trying to take advantage of sync delays is returning result from async code. This is not good strategy in JS. If you would like to return async results just use callbacks or more likely - Promises or Observables.






            share|improve this answer











            $endgroup$













            • $begingroup$
              I don't really understand what .apply() does. Can you explain? I've tried this page, but that's not very clear.
              $endgroup$
              – ericw31415
              Nov 14 '16 at 23:08












            • $begingroup$
              Check my updated answer.
              $endgroup$
              – rzelek
              Nov 14 '16 at 23:14










            • $begingroup$
              So are you saying that my function is flawed?
              $endgroup$
              – ericw31415
              Nov 15 '16 at 2:05














            3












            3








            3





            $begingroup$

            The Eval



            Eval is indeed, the monster. There are plenty of reasons why you should not use it, although there are some situations where you are forced to use it. For sure, this is not the requirement in yours situation. If func is a function, you can call it using .apply.



            function syncSetTimeout(func, ms, callback) {
            (function sync(done) {
            if (!done) {
            setTimeout(function() {
            func.apply(func);
            sync(true);
            }, ms);
            return;
            }
            callback.apply(callback);
            })();
            }


            Reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply



            Or event without apply:



            function syncSetTimeout(func, ms, callback) {
            (function sync(done) {
            if (!done) {
            setTimeout(function() {
            func();
            sync(true);
            }, ms);
            return;
            }
            callback();
            })();
            }


            The synchronous



            You need to know, that trying to make setTimeout() sync means that you have some very bad design idea behind. You should not do it and you will not be able to make it really sync without killing performance of the browser and UX of your app.



            I believe that you would like to create sync delay in your application. You are not the first who wants to do it (most of beginners or people with background from different language). You can take a look at answers to this question from stackoverflow: https://stackoverflow.com/questions/6921895/synchronous-delay-in-code-execution



            From the answer to linked question (by OverZealous):




            JavaScript is a single-threaded language. You cannot combine
            setTimeout and synchronous processing. What will happen is, the timer
            will lapse, but then the JS engine will wait to process the results
            until the current script completes.




            One reason people are trying to take advantage of sync delays is returning result from async code. This is not good strategy in JS. If you would like to return async results just use callbacks or more likely - Promises or Observables.






            share|improve this answer











            $endgroup$



            The Eval



            Eval is indeed, the monster. There are plenty of reasons why you should not use it, although there are some situations where you are forced to use it. For sure, this is not the requirement in yours situation. If func is a function, you can call it using .apply.



            function syncSetTimeout(func, ms, callback) {
            (function sync(done) {
            if (!done) {
            setTimeout(function() {
            func.apply(func);
            sync(true);
            }, ms);
            return;
            }
            callback.apply(callback);
            })();
            }


            Reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply



            Or event without apply:



            function syncSetTimeout(func, ms, callback) {
            (function sync(done) {
            if (!done) {
            setTimeout(function() {
            func();
            sync(true);
            }, ms);
            return;
            }
            callback();
            })();
            }


            The synchronous



            You need to know, that trying to make setTimeout() sync means that you have some very bad design idea behind. You should not do it and you will not be able to make it really sync without killing performance of the browser and UX of your app.



            I believe that you would like to create sync delay in your application. You are not the first who wants to do it (most of beginners or people with background from different language). You can take a look at answers to this question from stackoverflow: https://stackoverflow.com/questions/6921895/synchronous-delay-in-code-execution



            From the answer to linked question (by OverZealous):




            JavaScript is a single-threaded language. You cannot combine
            setTimeout and synchronous processing. What will happen is, the timer
            will lapse, but then the JS engine will wait to process the results
            until the current script completes.




            One reason people are trying to take advantage of sync delays is returning result from async code. This is not good strategy in JS. If you would like to return async results just use callbacks or more likely - Promises or Observables.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited May 23 '17 at 12:41









            Community

            1




            1










            answered Nov 14 '16 at 23:06









            rzelekrzelek

            1814




            1814












            • $begingroup$
              I don't really understand what .apply() does. Can you explain? I've tried this page, but that's not very clear.
              $endgroup$
              – ericw31415
              Nov 14 '16 at 23:08












            • $begingroup$
              Check my updated answer.
              $endgroup$
              – rzelek
              Nov 14 '16 at 23:14










            • $begingroup$
              So are you saying that my function is flawed?
              $endgroup$
              – ericw31415
              Nov 15 '16 at 2:05


















            • $begingroup$
              I don't really understand what .apply() does. Can you explain? I've tried this page, but that's not very clear.
              $endgroup$
              – ericw31415
              Nov 14 '16 at 23:08












            • $begingroup$
              Check my updated answer.
              $endgroup$
              – rzelek
              Nov 14 '16 at 23:14










            • $begingroup$
              So are you saying that my function is flawed?
              $endgroup$
              – ericw31415
              Nov 15 '16 at 2:05
















            $begingroup$
            I don't really understand what .apply() does. Can you explain? I've tried this page, but that's not very clear.
            $endgroup$
            – ericw31415
            Nov 14 '16 at 23:08






            $begingroup$
            I don't really understand what .apply() does. Can you explain? I've tried this page, but that's not very clear.
            $endgroup$
            – ericw31415
            Nov 14 '16 at 23:08














            $begingroup$
            Check my updated answer.
            $endgroup$
            – rzelek
            Nov 14 '16 at 23:14




            $begingroup$
            Check my updated answer.
            $endgroup$
            – rzelek
            Nov 14 '16 at 23:14












            $begingroup$
            So are you saying that my function is flawed?
            $endgroup$
            – ericw31415
            Nov 15 '16 at 2:05




            $begingroup$
            So are you saying that my function is flawed?
            $endgroup$
            – ericw31415
            Nov 15 '16 at 2:05













            0












            $begingroup$

            There's a simpler solution if you are using nodejs



            {code}



            await new Promise(done => setTimeout(() => done(), 180000));


            {/code}await new Promise(done => setTimeout(() => done(), 180000));





            share








            New contributor




            Anoop George is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
            Check out our Code of Conduct.






            $endgroup$


















              0












              $begingroup$

              There's a simpler solution if you are using nodejs



              {code}



              await new Promise(done => setTimeout(() => done(), 180000));


              {/code}await new Promise(done => setTimeout(() => done(), 180000));





              share








              New contributor




              Anoop George is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
              Check out our Code of Conduct.






              $endgroup$
















                0












                0








                0





                $begingroup$

                There's a simpler solution if you are using nodejs



                {code}



                await new Promise(done => setTimeout(() => done(), 180000));


                {/code}await new Promise(done => setTimeout(() => done(), 180000));





                share








                New contributor




                Anoop George is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                Check out our Code of Conduct.






                $endgroup$



                There's a simpler solution if you are using nodejs



                {code}



                await new Promise(done => setTimeout(() => done(), 180000));


                {/code}await new Promise(done => setTimeout(() => done(), 180000));






                share








                New contributor




                Anoop George is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                Check out our Code of Conduct.








                share


                share






                New contributor




                Anoop George is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                Check out our Code of Conduct.









                answered 7 mins ago









                Anoop GeorgeAnoop George

                101




                101




                New contributor




                Anoop George is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                Check out our Code of Conduct.





                New contributor





                Anoop George is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                Check out our Code of Conduct.






                Anoop George is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                Check out our Code of Conduct.






























                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Code Review Stack Exchange!


                    • 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.


                    Use MathJax to format equations. MathJax reference.


                    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%2fcodereview.stackexchange.com%2fquestions%2f147039%2fhelper-function-to-make-settimeout-synchronous%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

                    Список кардиналов, возведённых папой римским Каликстом III

                    Deduzione

                    Mysql.sock missing - “Can't connect to local MySQL server through socket”