Force a loop to wait two functions run sequentially











up vote
1
down vote

favorite












I have two functions that must be invoked sequentially within a loop, which in the code will loop 3 times. In the second function I have some animations and I do not know how to make the loop wait for the animation of the second function to end so that the loop goes to the next iteration.



LOOP FUNCTION



function startGame(){
emptyTab();

$("#movimentos-text").html(0)
$('.time').show()
$('.painel-tabuleiro').show();
$(".btn-reinicio").text("Reiniciar")


for(var i = 0; i < 3; i ++){
generateRandomCandys()
emptyElements()
}

}


FIRST FUNCTION



function generateRandomCandys(){
var elements = $(".painel-tabuleiro").children("div");

for (var i = 1; i <= elements.length; i++) {
for (var j = elements[i-1].childElementCount; j < 7; j++) {
//... some logic
}
}
}
}


SECOND FUNCTION



function emptyElements(){
// ... some logic
$(".equalElement").fadeOut()
$(".equalElement").fadeIn()
$(".equalElement").fadeOut()
$(".equalElement").fadeIn()
$(".equalElement").fadeOut(function() {
$(".equalElement").remove()
})
}


I've already tried using async and await, promise, interval and timeout but nothing worked.
I want to know how to do this:



 for(var i = 0; i < 3; i ++){
run first: generateRandomCandys()
run second: emptyElements()
wait the emptyElements() animations finish to increase i
}









share|improve this question


















  • 2




    Your emptyElements is calling fadeOut and fadeIn over and over again synchronously, are you sure that's what you want? Seems a bit pointless
    – CertainPerformance
    Nov 10 at 0:22






  • 1




    " I do not know how to make the loop wait for the animation" You cannot. for loops as inherently synchronous. Instead you need to use some kind of recursion: function doWork(i) { /* wait for async stuff */ if (i < 2) { doWork(i); } }; doWork(0); emptyElements should accept a callback to notify the caller when it is done.
    – Felix Kling
    Nov 10 at 0:23

















up vote
1
down vote

favorite












I have two functions that must be invoked sequentially within a loop, which in the code will loop 3 times. In the second function I have some animations and I do not know how to make the loop wait for the animation of the second function to end so that the loop goes to the next iteration.



LOOP FUNCTION



function startGame(){
emptyTab();

$("#movimentos-text").html(0)
$('.time').show()
$('.painel-tabuleiro').show();
$(".btn-reinicio").text("Reiniciar")


for(var i = 0; i < 3; i ++){
generateRandomCandys()
emptyElements()
}

}


FIRST FUNCTION



function generateRandomCandys(){
var elements = $(".painel-tabuleiro").children("div");

for (var i = 1; i <= elements.length; i++) {
for (var j = elements[i-1].childElementCount; j < 7; j++) {
//... some logic
}
}
}
}


SECOND FUNCTION



function emptyElements(){
// ... some logic
$(".equalElement").fadeOut()
$(".equalElement").fadeIn()
$(".equalElement").fadeOut()
$(".equalElement").fadeIn()
$(".equalElement").fadeOut(function() {
$(".equalElement").remove()
})
}


I've already tried using async and await, promise, interval and timeout but nothing worked.
I want to know how to do this:



 for(var i = 0; i < 3; i ++){
run first: generateRandomCandys()
run second: emptyElements()
wait the emptyElements() animations finish to increase i
}









share|improve this question


















  • 2




    Your emptyElements is calling fadeOut and fadeIn over and over again synchronously, are you sure that's what you want? Seems a bit pointless
    – CertainPerformance
    Nov 10 at 0:22






  • 1




    " I do not know how to make the loop wait for the animation" You cannot. for loops as inherently synchronous. Instead you need to use some kind of recursion: function doWork(i) { /* wait for async stuff */ if (i < 2) { doWork(i); } }; doWork(0); emptyElements should accept a callback to notify the caller when it is done.
    – Felix Kling
    Nov 10 at 0:23















up vote
1
down vote

favorite









up vote
1
down vote

favorite











I have two functions that must be invoked sequentially within a loop, which in the code will loop 3 times. In the second function I have some animations and I do not know how to make the loop wait for the animation of the second function to end so that the loop goes to the next iteration.



LOOP FUNCTION



function startGame(){
emptyTab();

$("#movimentos-text").html(0)
$('.time').show()
$('.painel-tabuleiro').show();
$(".btn-reinicio").text("Reiniciar")


for(var i = 0; i < 3; i ++){
generateRandomCandys()
emptyElements()
}

}


FIRST FUNCTION



function generateRandomCandys(){
var elements = $(".painel-tabuleiro").children("div");

for (var i = 1; i <= elements.length; i++) {
for (var j = elements[i-1].childElementCount; j < 7; j++) {
//... some logic
}
}
}
}


SECOND FUNCTION



function emptyElements(){
// ... some logic
$(".equalElement").fadeOut()
$(".equalElement").fadeIn()
$(".equalElement").fadeOut()
$(".equalElement").fadeIn()
$(".equalElement").fadeOut(function() {
$(".equalElement").remove()
})
}


I've already tried using async and await, promise, interval and timeout but nothing worked.
I want to know how to do this:



 for(var i = 0; i < 3; i ++){
run first: generateRandomCandys()
run second: emptyElements()
wait the emptyElements() animations finish to increase i
}









share|improve this question













I have two functions that must be invoked sequentially within a loop, which in the code will loop 3 times. In the second function I have some animations and I do not know how to make the loop wait for the animation of the second function to end so that the loop goes to the next iteration.



LOOP FUNCTION



function startGame(){
emptyTab();

$("#movimentos-text").html(0)
$('.time').show()
$('.painel-tabuleiro').show();
$(".btn-reinicio").text("Reiniciar")


for(var i = 0; i < 3; i ++){
generateRandomCandys()
emptyElements()
}

}


FIRST FUNCTION



function generateRandomCandys(){
var elements = $(".painel-tabuleiro").children("div");

for (var i = 1; i <= elements.length; i++) {
for (var j = elements[i-1].childElementCount; j < 7; j++) {
//... some logic
}
}
}
}


SECOND FUNCTION



function emptyElements(){
// ... some logic
$(".equalElement").fadeOut()
$(".equalElement").fadeIn()
$(".equalElement").fadeOut()
$(".equalElement").fadeIn()
$(".equalElement").fadeOut(function() {
$(".equalElement").remove()
})
}


I've already tried using async and await, promise, interval and timeout but nothing worked.
I want to know how to do this:



 for(var i = 0; i < 3; i ++){
run first: generateRandomCandys()
run second: emptyElements()
wait the emptyElements() animations finish to increase i
}






javascript jquery animation async-await






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 10 at 0:19









Henrique

154




154








  • 2




    Your emptyElements is calling fadeOut and fadeIn over and over again synchronously, are you sure that's what you want? Seems a bit pointless
    – CertainPerformance
    Nov 10 at 0:22






  • 1




    " I do not know how to make the loop wait for the animation" You cannot. for loops as inherently synchronous. Instead you need to use some kind of recursion: function doWork(i) { /* wait for async stuff */ if (i < 2) { doWork(i); } }; doWork(0); emptyElements should accept a callback to notify the caller when it is done.
    – Felix Kling
    Nov 10 at 0:23
















  • 2




    Your emptyElements is calling fadeOut and fadeIn over and over again synchronously, are you sure that's what you want? Seems a bit pointless
    – CertainPerformance
    Nov 10 at 0:22






  • 1




    " I do not know how to make the loop wait for the animation" You cannot. for loops as inherently synchronous. Instead you need to use some kind of recursion: function doWork(i) { /* wait for async stuff */ if (i < 2) { doWork(i); } }; doWork(0); emptyElements should accept a callback to notify the caller when it is done.
    – Felix Kling
    Nov 10 at 0:23










2




2




Your emptyElements is calling fadeOut and fadeIn over and over again synchronously, are you sure that's what you want? Seems a bit pointless
– CertainPerformance
Nov 10 at 0:22




Your emptyElements is calling fadeOut and fadeIn over and over again synchronously, are you sure that's what you want? Seems a bit pointless
– CertainPerformance
Nov 10 at 0:22




1




1




" I do not know how to make the loop wait for the animation" You cannot. for loops as inherently synchronous. Instead you need to use some kind of recursion: function doWork(i) { /* wait for async stuff */ if (i < 2) { doWork(i); } }; doWork(0); emptyElements should accept a callback to notify the caller when it is done.
– Felix Kling
Nov 10 at 0:23






" I do not know how to make the loop wait for the animation" You cannot. for loops as inherently synchronous. Instead you need to use some kind of recursion: function doWork(i) { /* wait for async stuff */ if (i < 2) { doWork(i); } }; doWork(0); emptyElements should accept a callback to notify the caller when it is done.
– Felix Kling
Nov 10 at 0:23














2 Answers
2






active

oldest

votes

















up vote
1
down vote



accepted










If you are OK with using await then you could chain the jQuery .promise() method, like this:



async function startGame(){
//^^^^
emptyTab();

$("#movimentos-text").html(0)
$('.time').show()
$('.painel-tabuleiro').show();
$(".btn-reinicio").text("Reiniciar")

for(var i = 0; i < 3; i ++){
generateRandomCandys()
await emptyElements()
//^^^^^
}
}


Second function:



async function emptyElements(){
//^^^^
return $(".equalElement").fadeOut().fadeIn().fadeOut().fadeIn().fadeOut()
//^^^^
.promise().then(()=> $(".equalElement").remove())
//^^^^^^^^^^^^^^^^
}





share|improve this answer




























    up vote
    0
    down vote













    You can use some sort of recursion as @Felix Kling suggested.



    Then, to avoid triggering the callback for every .equalElement object, use $.when():




    Provides a way to execute callback functions based on zero or more Thenable objects, usually Deferred objects that represent asynchronous events.







    var iteration = 0;

    function showCandys() {
    generateRandomCandys();
    emptyElements();
    }

    function generateRandomCandys() {
    $("div div").each(function() {
    if (Math.random() <= 0.5) {
    var candy = $("<span></span>").text("CANDY").addClass("equalElement");
    $(this).append(candy);
    }
    });
    }

    function emptyElements() {
    $.when($(".equalElement").fadeIn().fadeOut().fadeIn().fadeOut()).then(function() {
    $(".equalElement").remove();
    iteration++;
    if (iteration < 3) showCandys();
    })
    }

    showCandys();

    div div {
    width: 100px;
    height: 100px;
    border: 1px solid red;
    }

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <div>
    <div></div>
    <div></div>
    <div></div>
    </div>








    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',
      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%2f53234901%2fforce-a-loop-to-wait-two-functions-run-sequentially%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








      up vote
      1
      down vote



      accepted










      If you are OK with using await then you could chain the jQuery .promise() method, like this:



      async function startGame(){
      //^^^^
      emptyTab();

      $("#movimentos-text").html(0)
      $('.time').show()
      $('.painel-tabuleiro').show();
      $(".btn-reinicio").text("Reiniciar")

      for(var i = 0; i < 3; i ++){
      generateRandomCandys()
      await emptyElements()
      //^^^^^
      }
      }


      Second function:



      async function emptyElements(){
      //^^^^
      return $(".equalElement").fadeOut().fadeIn().fadeOut().fadeIn().fadeOut()
      //^^^^
      .promise().then(()=> $(".equalElement").remove())
      //^^^^^^^^^^^^^^^^
      }





      share|improve this answer

























        up vote
        1
        down vote



        accepted










        If you are OK with using await then you could chain the jQuery .promise() method, like this:



        async function startGame(){
        //^^^^
        emptyTab();

        $("#movimentos-text").html(0)
        $('.time').show()
        $('.painel-tabuleiro').show();
        $(".btn-reinicio").text("Reiniciar")

        for(var i = 0; i < 3; i ++){
        generateRandomCandys()
        await emptyElements()
        //^^^^^
        }
        }


        Second function:



        async function emptyElements(){
        //^^^^
        return $(".equalElement").fadeOut().fadeIn().fadeOut().fadeIn().fadeOut()
        //^^^^
        .promise().then(()=> $(".equalElement").remove())
        //^^^^^^^^^^^^^^^^
        }





        share|improve this answer























          up vote
          1
          down vote



          accepted







          up vote
          1
          down vote



          accepted






          If you are OK with using await then you could chain the jQuery .promise() method, like this:



          async function startGame(){
          //^^^^
          emptyTab();

          $("#movimentos-text").html(0)
          $('.time').show()
          $('.painel-tabuleiro').show();
          $(".btn-reinicio").text("Reiniciar")

          for(var i = 0; i < 3; i ++){
          generateRandomCandys()
          await emptyElements()
          //^^^^^
          }
          }


          Second function:



          async function emptyElements(){
          //^^^^
          return $(".equalElement").fadeOut().fadeIn().fadeOut().fadeIn().fadeOut()
          //^^^^
          .promise().then(()=> $(".equalElement").remove())
          //^^^^^^^^^^^^^^^^
          }





          share|improve this answer












          If you are OK with using await then you could chain the jQuery .promise() method, like this:



          async function startGame(){
          //^^^^
          emptyTab();

          $("#movimentos-text").html(0)
          $('.time').show()
          $('.painel-tabuleiro').show();
          $(".btn-reinicio").text("Reiniciar")

          for(var i = 0; i < 3; i ++){
          generateRandomCandys()
          await emptyElements()
          //^^^^^
          }
          }


          Second function:



          async function emptyElements(){
          //^^^^
          return $(".equalElement").fadeOut().fadeIn().fadeOut().fadeIn().fadeOut()
          //^^^^
          .promise().then(()=> $(".equalElement").remove())
          //^^^^^^^^^^^^^^^^
          }






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 10 at 0:42









          trincot

          114k1477109




          114k1477109
























              up vote
              0
              down vote













              You can use some sort of recursion as @Felix Kling suggested.



              Then, to avoid triggering the callback for every .equalElement object, use $.when():




              Provides a way to execute callback functions based on zero or more Thenable objects, usually Deferred objects that represent asynchronous events.







              var iteration = 0;

              function showCandys() {
              generateRandomCandys();
              emptyElements();
              }

              function generateRandomCandys() {
              $("div div").each(function() {
              if (Math.random() <= 0.5) {
              var candy = $("<span></span>").text("CANDY").addClass("equalElement");
              $(this).append(candy);
              }
              });
              }

              function emptyElements() {
              $.when($(".equalElement").fadeIn().fadeOut().fadeIn().fadeOut()).then(function() {
              $(".equalElement").remove();
              iteration++;
              if (iteration < 3) showCandys();
              })
              }

              showCandys();

              div div {
              width: 100px;
              height: 100px;
              border: 1px solid red;
              }

              <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
              <div>
              <div></div>
              <div></div>
              <div></div>
              </div>








              share|improve this answer

























                up vote
                0
                down vote













                You can use some sort of recursion as @Felix Kling suggested.



                Then, to avoid triggering the callback for every .equalElement object, use $.when():




                Provides a way to execute callback functions based on zero or more Thenable objects, usually Deferred objects that represent asynchronous events.







                var iteration = 0;

                function showCandys() {
                generateRandomCandys();
                emptyElements();
                }

                function generateRandomCandys() {
                $("div div").each(function() {
                if (Math.random() <= 0.5) {
                var candy = $("<span></span>").text("CANDY").addClass("equalElement");
                $(this).append(candy);
                }
                });
                }

                function emptyElements() {
                $.when($(".equalElement").fadeIn().fadeOut().fadeIn().fadeOut()).then(function() {
                $(".equalElement").remove();
                iteration++;
                if (iteration < 3) showCandys();
                })
                }

                showCandys();

                div div {
                width: 100px;
                height: 100px;
                border: 1px solid red;
                }

                <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
                <div>
                <div></div>
                <div></div>
                <div></div>
                </div>








                share|improve this answer























                  up vote
                  0
                  down vote










                  up vote
                  0
                  down vote









                  You can use some sort of recursion as @Felix Kling suggested.



                  Then, to avoid triggering the callback for every .equalElement object, use $.when():




                  Provides a way to execute callback functions based on zero or more Thenable objects, usually Deferred objects that represent asynchronous events.







                  var iteration = 0;

                  function showCandys() {
                  generateRandomCandys();
                  emptyElements();
                  }

                  function generateRandomCandys() {
                  $("div div").each(function() {
                  if (Math.random() <= 0.5) {
                  var candy = $("<span></span>").text("CANDY").addClass("equalElement");
                  $(this).append(candy);
                  }
                  });
                  }

                  function emptyElements() {
                  $.when($(".equalElement").fadeIn().fadeOut().fadeIn().fadeOut()).then(function() {
                  $(".equalElement").remove();
                  iteration++;
                  if (iteration < 3) showCandys();
                  })
                  }

                  showCandys();

                  div div {
                  width: 100px;
                  height: 100px;
                  border: 1px solid red;
                  }

                  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
                  <div>
                  <div></div>
                  <div></div>
                  <div></div>
                  </div>








                  share|improve this answer












                  You can use some sort of recursion as @Felix Kling suggested.



                  Then, to avoid triggering the callback for every .equalElement object, use $.when():




                  Provides a way to execute callback functions based on zero or more Thenable objects, usually Deferred objects that represent asynchronous events.







                  var iteration = 0;

                  function showCandys() {
                  generateRandomCandys();
                  emptyElements();
                  }

                  function generateRandomCandys() {
                  $("div div").each(function() {
                  if (Math.random() <= 0.5) {
                  var candy = $("<span></span>").text("CANDY").addClass("equalElement");
                  $(this).append(candy);
                  }
                  });
                  }

                  function emptyElements() {
                  $.when($(".equalElement").fadeIn().fadeOut().fadeIn().fadeOut()).then(function() {
                  $(".equalElement").remove();
                  iteration++;
                  if (iteration < 3) showCandys();
                  })
                  }

                  showCandys();

                  div div {
                  width: 100px;
                  height: 100px;
                  border: 1px solid red;
                  }

                  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
                  <div>
                  <div></div>
                  <div></div>
                  <div></div>
                  </div>








                  var iteration = 0;

                  function showCandys() {
                  generateRandomCandys();
                  emptyElements();
                  }

                  function generateRandomCandys() {
                  $("div div").each(function() {
                  if (Math.random() <= 0.5) {
                  var candy = $("<span></span>").text("CANDY").addClass("equalElement");
                  $(this).append(candy);
                  }
                  });
                  }

                  function emptyElements() {
                  $.when($(".equalElement").fadeIn().fadeOut().fadeIn().fadeOut()).then(function() {
                  $(".equalElement").remove();
                  iteration++;
                  if (iteration < 3) showCandys();
                  })
                  }

                  showCandys();

                  div div {
                  width: 100px;
                  height: 100px;
                  border: 1px solid red;
                  }

                  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
                  <div>
                  <div></div>
                  <div></div>
                  <div></div>
                  </div>





                  var iteration = 0;

                  function showCandys() {
                  generateRandomCandys();
                  emptyElements();
                  }

                  function generateRandomCandys() {
                  $("div div").each(function() {
                  if (Math.random() <= 0.5) {
                  var candy = $("<span></span>").text("CANDY").addClass("equalElement");
                  $(this).append(candy);
                  }
                  });
                  }

                  function emptyElements() {
                  $.when($(".equalElement").fadeIn().fadeOut().fadeIn().fadeOut()).then(function() {
                  $(".equalElement").remove();
                  iteration++;
                  if (iteration < 3) showCandys();
                  })
                  }

                  showCandys();

                  div div {
                  width: 100px;
                  height: 100px;
                  border: 1px solid red;
                  }

                  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
                  <div>
                  <div></div>
                  <div></div>
                  <div></div>
                  </div>






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 10 at 1:20









                  David

                  2,93011234




                  2,93011234






























                      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.





                      Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                      Please pay close attention to the following guidance:


                      • 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%2f53234901%2fforce-a-loop-to-wait-two-functions-run-sequentially%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

                      Schultheiß

                      Verwaltungsgliederung Dänemarks

                      Liste der Kulturdenkmale in Wilsdruff