Why is my callback firing before my for loop completes?












0















learner here...I have used the callback technique I've learned here to try to get my alert to fire after I have appended my HTML. No matter what I do, my alert fires first, then my my HTML is appended. Based on what I've read, this shouldn't be happening. What am I missing here? I'd like my HTML to paint completely (by appending) before the alert fires. I appreciate any insight you may have!






$(document).ready(function() {
let data = {
d: {
results: [{
Title: 'title1'
}, {
Title: 'title2'
}]
}
};
createHTML(data, callback);
});


/*NOTE: 'data' is the result of a ajax call which is not included here for brevity*/
function createHTML(data, callback) {
var tabOneWrap = $('.tabOneWrap');
var arr = data.d.results;
for (var i in arr) {
var item = arr[i];
tabOneWrap.append(
'<div class="requestWrap">' + item.Title + '</div>'
);
}
callback();
}

function callback() {
alert("aloha");
}

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












share|improve this question





























    0















    learner here...I have used the callback technique I've learned here to try to get my alert to fire after I have appended my HTML. No matter what I do, my alert fires first, then my my HTML is appended. Based on what I've read, this shouldn't be happening. What am I missing here? I'd like my HTML to paint completely (by appending) before the alert fires. I appreciate any insight you may have!






    $(document).ready(function() {
    let data = {
    d: {
    results: [{
    Title: 'title1'
    }, {
    Title: 'title2'
    }]
    }
    };
    createHTML(data, callback);
    });


    /*NOTE: 'data' is the result of a ajax call which is not included here for brevity*/
    function createHTML(data, callback) {
    var tabOneWrap = $('.tabOneWrap');
    var arr = data.d.results;
    for (var i in arr) {
    var item = arr[i];
    tabOneWrap.append(
    '<div class="requestWrap">' + item.Title + '</div>'
    );
    }
    callback();
    }

    function callback() {
    alert("aloha");
    }

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












    share|improve this question



























      0












      0








      0








      learner here...I have used the callback technique I've learned here to try to get my alert to fire after I have appended my HTML. No matter what I do, my alert fires first, then my my HTML is appended. Based on what I've read, this shouldn't be happening. What am I missing here? I'd like my HTML to paint completely (by appending) before the alert fires. I appreciate any insight you may have!






      $(document).ready(function() {
      let data = {
      d: {
      results: [{
      Title: 'title1'
      }, {
      Title: 'title2'
      }]
      }
      };
      createHTML(data, callback);
      });


      /*NOTE: 'data' is the result of a ajax call which is not included here for brevity*/
      function createHTML(data, callback) {
      var tabOneWrap = $('.tabOneWrap');
      var arr = data.d.results;
      for (var i in arr) {
      var item = arr[i];
      tabOneWrap.append(
      '<div class="requestWrap">' + item.Title + '</div>'
      );
      }
      callback();
      }

      function callback() {
      alert("aloha");
      }

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












      share|improve this question
















      learner here...I have used the callback technique I've learned here to try to get my alert to fire after I have appended my HTML. No matter what I do, my alert fires first, then my my HTML is appended. Based on what I've read, this shouldn't be happening. What am I missing here? I'd like my HTML to paint completely (by appending) before the alert fires. I appreciate any insight you may have!






      $(document).ready(function() {
      let data = {
      d: {
      results: [{
      Title: 'title1'
      }, {
      Title: 'title2'
      }]
      }
      };
      createHTML(data, callback);
      });


      /*NOTE: 'data' is the result of a ajax call which is not included here for brevity*/
      function createHTML(data, callback) {
      var tabOneWrap = $('.tabOneWrap');
      var arr = data.d.results;
      for (var i in arr) {
      var item = arr[i];
      tabOneWrap.append(
      '<div class="requestWrap">' + item.Title + '</div>'
      );
      }
      callback();
      }

      function callback() {
      alert("aloha");
      }

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








      $(document).ready(function() {
      let data = {
      d: {
      results: [{
      Title: 'title1'
      }, {
      Title: 'title2'
      }]
      }
      };
      createHTML(data, callback);
      });


      /*NOTE: 'data' is the result of a ajax call which is not included here for brevity*/
      function createHTML(data, callback) {
      var tabOneWrap = $('.tabOneWrap');
      var arr = data.d.results;
      for (var i in arr) {
      var item = arr[i];
      tabOneWrap.append(
      '<div class="requestWrap">' + item.Title + '</div>'
      );
      }
      callback();
      }

      function callback() {
      alert("aloha");
      }

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





      $(document).ready(function() {
      let data = {
      d: {
      results: [{
      Title: 'title1'
      }, {
      Title: 'title2'
      }]
      }
      };
      createHTML(data, callback);
      });


      /*NOTE: 'data' is the result of a ajax call which is not included here for brevity*/
      function createHTML(data, callback) {
      var tabOneWrap = $('.tabOneWrap');
      var arr = data.d.results;
      for (var i in arr) {
      var item = arr[i];
      tabOneWrap.append(
      '<div class="requestWrap">' + item.Title + '</div>'
      );
      }
      callback();
      }

      function callback() {
      alert("aloha");
      }

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






      javascript callback append






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 21 '18 at 19:18









      Randy Casburn

      4,9891318




      4,9891318










      asked Nov 21 '18 at 19:13









      loady toadloady toad

      286




      286
























          2 Answers
          2






          active

          oldest

          votes


















          3














          Using alert() is a poor debugging tool. It stops anything else from happening including repainting the document. Logging things to a console (F12 in browser) is much better



          I've added some logging inside the loop and in the callback and you can see the order is as you expect. All else is the same






          var data = {d:{results:[{Title:'Item 1'},{Title:'Item 2'}]}};

          $(document).ready(function(){
          createHTML(data,callback);
          });

          /*NOTE: 'data' is the result of a ajax call which is not included here for brevity*/
          function createHTML(data,callback){
          var tabOneWrap = $('.tabOneWrap');
          var arr = data.d.results;
          for(var i in arr){
          console.log('Loop :: ',i)
          var item = arr[i];
          tabOneWrap.append(
          '<div class="requestWrap">'+item.Title+'</div>'
          );
          }
          console.log('Before callback')
          callback();
          }

          function callback(){
          console.log("aloha");
          }

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








          share|improve this answer


























          • @PatrickRoberts - That was added after I submitted my comment. So thanks to charilettfl. I've removed my comment. Thanks - great answer!

            – Randy Casburn
            Nov 21 '18 at 19:25











          • Oh, didn't realize it was edited.

            – Patrick Roberts
            Nov 21 '18 at 19:26



















          1














          Really, there is no good answer to this, because it is how the browser/js runtime is built to operate. The quick and dirty solution is to wrap your callback in a setTimeout or, better yet, requestAnimationFrame:



          // setTimeout(callback, 0);
          requestAnimationFrame(callback);


          This will ensure that the event loop can “wrap around,” do some painting, and then execute your callback.



          As long as synchronous code is being executed, the other pieces of the runtime machinery will just be waiting their turn. It is not until an asynchronous operation happens (like a setTimeout or RAF), that the browser will say, “Ok, nothing else to do, let’s paint the screen with any changes and have a look in the queue for any other JS that is ready for execution.”



          Here is my favorite talk on the topic. It might be a little deep if you’re new to the craft, but it will give you a leg up going forward if you pay close attention.



          https://youtu.be/cCOL7MC4Pl0






          share|improve this answer





















          • 1





            Or more appropriately requestAnimationFrame(callback);

            – Patrick Roberts
            Nov 21 '18 at 19:25













          • Patrick, that is an excellent point. I will adjust my answer.

            – Ben Steward
            Nov 21 '18 at 19:36











          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%2f53419061%2fwhy-is-my-callback-firing-before-my-for-loop-completes%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














          Using alert() is a poor debugging tool. It stops anything else from happening including repainting the document. Logging things to a console (F12 in browser) is much better



          I've added some logging inside the loop and in the callback and you can see the order is as you expect. All else is the same






          var data = {d:{results:[{Title:'Item 1'},{Title:'Item 2'}]}};

          $(document).ready(function(){
          createHTML(data,callback);
          });

          /*NOTE: 'data' is the result of a ajax call which is not included here for brevity*/
          function createHTML(data,callback){
          var tabOneWrap = $('.tabOneWrap');
          var arr = data.d.results;
          for(var i in arr){
          console.log('Loop :: ',i)
          var item = arr[i];
          tabOneWrap.append(
          '<div class="requestWrap">'+item.Title+'</div>'
          );
          }
          console.log('Before callback')
          callback();
          }

          function callback(){
          console.log("aloha");
          }

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








          share|improve this answer


























          • @PatrickRoberts - That was added after I submitted my comment. So thanks to charilettfl. I've removed my comment. Thanks - great answer!

            – Randy Casburn
            Nov 21 '18 at 19:25











          • Oh, didn't realize it was edited.

            – Patrick Roberts
            Nov 21 '18 at 19:26
















          3














          Using alert() is a poor debugging tool. It stops anything else from happening including repainting the document. Logging things to a console (F12 in browser) is much better



          I've added some logging inside the loop and in the callback and you can see the order is as you expect. All else is the same






          var data = {d:{results:[{Title:'Item 1'},{Title:'Item 2'}]}};

          $(document).ready(function(){
          createHTML(data,callback);
          });

          /*NOTE: 'data' is the result of a ajax call which is not included here for brevity*/
          function createHTML(data,callback){
          var tabOneWrap = $('.tabOneWrap');
          var arr = data.d.results;
          for(var i in arr){
          console.log('Loop :: ',i)
          var item = arr[i];
          tabOneWrap.append(
          '<div class="requestWrap">'+item.Title+'</div>'
          );
          }
          console.log('Before callback')
          callback();
          }

          function callback(){
          console.log("aloha");
          }

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








          share|improve this answer


























          • @PatrickRoberts - That was added after I submitted my comment. So thanks to charilettfl. I've removed my comment. Thanks - great answer!

            – Randy Casburn
            Nov 21 '18 at 19:25











          • Oh, didn't realize it was edited.

            – Patrick Roberts
            Nov 21 '18 at 19:26














          3












          3








          3







          Using alert() is a poor debugging tool. It stops anything else from happening including repainting the document. Logging things to a console (F12 in browser) is much better



          I've added some logging inside the loop and in the callback and you can see the order is as you expect. All else is the same






          var data = {d:{results:[{Title:'Item 1'},{Title:'Item 2'}]}};

          $(document).ready(function(){
          createHTML(data,callback);
          });

          /*NOTE: 'data' is the result of a ajax call which is not included here for brevity*/
          function createHTML(data,callback){
          var tabOneWrap = $('.tabOneWrap');
          var arr = data.d.results;
          for(var i in arr){
          console.log('Loop :: ',i)
          var item = arr[i];
          tabOneWrap.append(
          '<div class="requestWrap">'+item.Title+'</div>'
          );
          }
          console.log('Before callback')
          callback();
          }

          function callback(){
          console.log("aloha");
          }

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








          share|improve this answer















          Using alert() is a poor debugging tool. It stops anything else from happening including repainting the document. Logging things to a console (F12 in browser) is much better



          I've added some logging inside the loop and in the callback and you can see the order is as you expect. All else is the same






          var data = {d:{results:[{Title:'Item 1'},{Title:'Item 2'}]}};

          $(document).ready(function(){
          createHTML(data,callback);
          });

          /*NOTE: 'data' is the result of a ajax call which is not included here for brevity*/
          function createHTML(data,callback){
          var tabOneWrap = $('.tabOneWrap');
          var arr = data.d.results;
          for(var i in arr){
          console.log('Loop :: ',i)
          var item = arr[i];
          tabOneWrap.append(
          '<div class="requestWrap">'+item.Title+'</div>'
          );
          }
          console.log('Before callback')
          callback();
          }

          function callback(){
          console.log("aloha");
          }

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








          var data = {d:{results:[{Title:'Item 1'},{Title:'Item 2'}]}};

          $(document).ready(function(){
          createHTML(data,callback);
          });

          /*NOTE: 'data' is the result of a ajax call which is not included here for brevity*/
          function createHTML(data,callback){
          var tabOneWrap = $('.tabOneWrap');
          var arr = data.d.results;
          for(var i in arr){
          console.log('Loop :: ',i)
          var item = arr[i];
          tabOneWrap.append(
          '<div class="requestWrap">'+item.Title+'</div>'
          );
          }
          console.log('Before callback')
          callback();
          }

          function callback(){
          console.log("aloha");
          }

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





          var data = {d:{results:[{Title:'Item 1'},{Title:'Item 2'}]}};

          $(document).ready(function(){
          createHTML(data,callback);
          });

          /*NOTE: 'data' is the result of a ajax call which is not included here for brevity*/
          function createHTML(data,callback){
          var tabOneWrap = $('.tabOneWrap');
          var arr = data.d.results;
          for(var i in arr){
          console.log('Loop :: ',i)
          var item = arr[i];
          tabOneWrap.append(
          '<div class="requestWrap">'+item.Title+'</div>'
          );
          }
          console.log('Before callback')
          callback();
          }

          function callback(){
          console.log("aloha");
          }

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






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 21 '18 at 19:30

























          answered Nov 21 '18 at 19:20









          charlietflcharlietfl

          139k1389122




          139k1389122













          • @PatrickRoberts - That was added after I submitted my comment. So thanks to charilettfl. I've removed my comment. Thanks - great answer!

            – Randy Casburn
            Nov 21 '18 at 19:25











          • Oh, didn't realize it was edited.

            – Patrick Roberts
            Nov 21 '18 at 19:26



















          • @PatrickRoberts - That was added after I submitted my comment. So thanks to charilettfl. I've removed my comment. Thanks - great answer!

            – Randy Casburn
            Nov 21 '18 at 19:25











          • Oh, didn't realize it was edited.

            – Patrick Roberts
            Nov 21 '18 at 19:26

















          @PatrickRoberts - That was added after I submitted my comment. So thanks to charilettfl. I've removed my comment. Thanks - great answer!

          – Randy Casburn
          Nov 21 '18 at 19:25





          @PatrickRoberts - That was added after I submitted my comment. So thanks to charilettfl. I've removed my comment. Thanks - great answer!

          – Randy Casburn
          Nov 21 '18 at 19:25













          Oh, didn't realize it was edited.

          – Patrick Roberts
          Nov 21 '18 at 19:26





          Oh, didn't realize it was edited.

          – Patrick Roberts
          Nov 21 '18 at 19:26













          1














          Really, there is no good answer to this, because it is how the browser/js runtime is built to operate. The quick and dirty solution is to wrap your callback in a setTimeout or, better yet, requestAnimationFrame:



          // setTimeout(callback, 0);
          requestAnimationFrame(callback);


          This will ensure that the event loop can “wrap around,” do some painting, and then execute your callback.



          As long as synchronous code is being executed, the other pieces of the runtime machinery will just be waiting their turn. It is not until an asynchronous operation happens (like a setTimeout or RAF), that the browser will say, “Ok, nothing else to do, let’s paint the screen with any changes and have a look in the queue for any other JS that is ready for execution.”



          Here is my favorite talk on the topic. It might be a little deep if you’re new to the craft, but it will give you a leg up going forward if you pay close attention.



          https://youtu.be/cCOL7MC4Pl0






          share|improve this answer





















          • 1





            Or more appropriately requestAnimationFrame(callback);

            – Patrick Roberts
            Nov 21 '18 at 19:25













          • Patrick, that is an excellent point. I will adjust my answer.

            – Ben Steward
            Nov 21 '18 at 19:36
















          1














          Really, there is no good answer to this, because it is how the browser/js runtime is built to operate. The quick and dirty solution is to wrap your callback in a setTimeout or, better yet, requestAnimationFrame:



          // setTimeout(callback, 0);
          requestAnimationFrame(callback);


          This will ensure that the event loop can “wrap around,” do some painting, and then execute your callback.



          As long as synchronous code is being executed, the other pieces of the runtime machinery will just be waiting their turn. It is not until an asynchronous operation happens (like a setTimeout or RAF), that the browser will say, “Ok, nothing else to do, let’s paint the screen with any changes and have a look in the queue for any other JS that is ready for execution.”



          Here is my favorite talk on the topic. It might be a little deep if you’re new to the craft, but it will give you a leg up going forward if you pay close attention.



          https://youtu.be/cCOL7MC4Pl0






          share|improve this answer





















          • 1





            Or more appropriately requestAnimationFrame(callback);

            – Patrick Roberts
            Nov 21 '18 at 19:25













          • Patrick, that is an excellent point. I will adjust my answer.

            – Ben Steward
            Nov 21 '18 at 19:36














          1












          1








          1







          Really, there is no good answer to this, because it is how the browser/js runtime is built to operate. The quick and dirty solution is to wrap your callback in a setTimeout or, better yet, requestAnimationFrame:



          // setTimeout(callback, 0);
          requestAnimationFrame(callback);


          This will ensure that the event loop can “wrap around,” do some painting, and then execute your callback.



          As long as synchronous code is being executed, the other pieces of the runtime machinery will just be waiting their turn. It is not until an asynchronous operation happens (like a setTimeout or RAF), that the browser will say, “Ok, nothing else to do, let’s paint the screen with any changes and have a look in the queue for any other JS that is ready for execution.”



          Here is my favorite talk on the topic. It might be a little deep if you’re new to the craft, but it will give you a leg up going forward if you pay close attention.



          https://youtu.be/cCOL7MC4Pl0






          share|improve this answer















          Really, there is no good answer to this, because it is how the browser/js runtime is built to operate. The quick and dirty solution is to wrap your callback in a setTimeout or, better yet, requestAnimationFrame:



          // setTimeout(callback, 0);
          requestAnimationFrame(callback);


          This will ensure that the event loop can “wrap around,” do some painting, and then execute your callback.



          As long as synchronous code is being executed, the other pieces of the runtime machinery will just be waiting their turn. It is not until an asynchronous operation happens (like a setTimeout or RAF), that the browser will say, “Ok, nothing else to do, let’s paint the screen with any changes and have a look in the queue for any other JS that is ready for execution.”



          Here is my favorite talk on the topic. It might be a little deep if you’re new to the craft, but it will give you a leg up going forward if you pay close attention.



          https://youtu.be/cCOL7MC4Pl0







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 21 '18 at 19:38

























          answered Nov 21 '18 at 19:24









          Ben StewardBen Steward

          1,135315




          1,135315








          • 1





            Or more appropriately requestAnimationFrame(callback);

            – Patrick Roberts
            Nov 21 '18 at 19:25













          • Patrick, that is an excellent point. I will adjust my answer.

            – Ben Steward
            Nov 21 '18 at 19:36














          • 1





            Or more appropriately requestAnimationFrame(callback);

            – Patrick Roberts
            Nov 21 '18 at 19:25













          • Patrick, that is an excellent point. I will adjust my answer.

            – Ben Steward
            Nov 21 '18 at 19:36








          1




          1





          Or more appropriately requestAnimationFrame(callback);

          – Patrick Roberts
          Nov 21 '18 at 19:25







          Or more appropriately requestAnimationFrame(callback);

          – Patrick Roberts
          Nov 21 '18 at 19:25















          Patrick, that is an excellent point. I will adjust my answer.

          – Ben Steward
          Nov 21 '18 at 19:36





          Patrick, that is an excellent point. I will adjust my answer.

          – Ben Steward
          Nov 21 '18 at 19:36


















          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%2f53419061%2fwhy-is-my-callback-firing-before-my-for-loop-completes%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

          MongoDB - Not Authorized To Execute Command

          How to fix TextFormField cause rebuild widget in Flutter

          in spring boot 2.1 many test slices are not allowed anymore due to multiple @BootstrapWith