为什么在for循环完成之前触发回调?

时间:2018-11-21 19:13:14

标签: javascript callback append

这里的学习者...我已经使用了here所学的回调技术来尝试在添加HTML后触发警报。无论我做什么,我的警报都会首先触发,然后附加我的HTML。根据我的阅读,这不应该发生。我在这里想念什么?我希望我的HTML在警报触发之前完全绘制(通过追加)。感谢您有任何见识!

$(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>

2 个答案:

答案 0 :(得分:3)

使用alert()是一个较差的调试工具。它可以阻止其他任何事情发生,包括重新绘制文档。将内容记录到控制台(浏览器中为F12)会更好

我在循环和回调中添加了一些日志记录,您可以看到顺序是您期望的。其他都一样

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>

答案 1 :(得分:1)

真的,对此没有很好的答案,因为这是构建浏览器/ js运行时运行的方式。快速而肮脏的解决方案是将您的回调包装在setTimeout或更好的是requestAnimationFrame中:

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

这将确保事件循环可以“环绕”,进行绘制,然后执行回调。

只要正在执行同步代码,其他运行时机器都将等待它们的运行。直到发生异步操作(如setTimeout或RAF),浏览器才会说:“好吧,别无所求,让我们用任何更改来绘制屏幕,​​并在队列中查找其他任何JS。准备执行。”

这是我最喜欢的话题话题。如果您不熟悉此技术,可能会有点深,但是如果您密切注意,它将使您有前进的脚步。

https://youtu.be/cCOL7MC4Pl0