简体   繁体   English

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

[英]Why is my callback firing before my for loop completes?

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. 在这里学习。我已经使用了回调的技术我学到这里 ,试图让我的警惕火我已经附加我的HTML后。 No matter what I do, my alert fires first, then my my HTML is appended. 无论我做什么,我的警报都会首先触发,然后附加我的HTML。 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. 我希望我的HTML在警报触发之前完全绘制(通过追加)。 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> 

Using alert() is a poor debugging tool. 使用alert()是一个较差的调试工具。 It stops anything else from happening including repainting the document. 它可以阻止其他任何事情发生,包括重新绘制文档。 Logging things to a console (F12 in browser) is much better 将内容记录到控制台(浏览器中为F12)会更好

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> 

Really, there is no good answer to this, because it is how the browser/js runtime is built to operate. 确实,对此没有很好的答案,因为这是构建浏览器/ js运行时的方式。 The quick and dirty solution is to wrap your callback in a setTimeout or, better yet, requestAnimationFrame: 快速而肮脏的解决方案是将您的回调包装在setTimeout或更好的是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.” 直到发生异步操作(如setTimeout或RAF),浏览器才会说:“好吧,别无所求,让我们用任何更改来绘制屏幕,​​并在队列中查找其他任何JS。准备执行。”

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 https://youtu.be/cCOL7MC4Pl0

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM