Ember JS中无延时加载器不显示问题咨询
问题
我正在使用Ember JS开发应用,希望在更新DOM前显示全屏加载器,相关代码如下:
table.hbs代码
<div id="full-loader"></div> {{#each data as |val|}} <p>val</p> {{/each}} <button {{action 'updateData'}}>Add More</button>
table.js代码
addValues(){ for(var i=0;i<100;i++){ data.pushObject(i) } } @action updateData(){ Ember.$("#full-loader").css("display","block"); addValues(); } didRender(){ Ember.$("#full-loader").css("display","none"); }
当前全屏加载器始终无法显示,但在调用addValues()时使用setTimeout()后,加载器就能正常显示,请问这是什么原因?
原因分析
这是JavaScript单线程事件循环机制结合Ember渲染逻辑导致的:
- 浏览器的UI渲染和JavaScript代码执行共享同一个线程,必须等当前同步任务全部执行完毕,才会处理UI渲染队列。
- 在
updateData方法里,你先设置加载器显示,紧接着同步执行addValues的循环操作——这个循环会持续占用线程,浏览器根本没机会更新DOM来显示加载器。 - 等
addValues执行完成后,Ember才会触发渲染流程,随后didRender钩子立刻将加载器隐藏,所以你看不到加载器出现。
而使用setTimeout()时,addValues会被放入宏任务队列。当前同步任务(设置加载器显示)执行完后,浏览器会先处理UI渲染,显示加载器,之后才会执行addValues的循环操作,这样加载器就能正常展示了。
内容的提问来源于stack exchange,提问作者Subash A
相关产品推荐
相关产品推荐

