【问题标题】:Deferred in click event with jquery for ui render使用 jquery 延迟单击事件以进行 ui 渲染
【发布时间】:2016-07-31 08:29:33
【问题描述】:
我有这个代码:
$("input#drawAllRoutes").click(function (e) {
console.log("drawAllRoutes: Start Drawing");
showWaitPanel();
...
//foreach routeElement add vector layer on map
...
console.log("drawAllRoutes: Ok ");
hideWaitPanel();
})
我会有这种行为:
- 显示等待面板在 div 中添加正确的类:这是由 showWaitPanel() 完成的;
- 之后,我在 openlayers3 地图中添加了大量矢量图层
- 完成后,使用 hideWaitPanel() 将等待面板设置为隐藏,从 div 中删除一个类
问题在于,使用此代码时,UI 不会呈现,因为矢量绘图需要更多资源,因此会冻结 UI。
所以我没有看到等待面板,并且 UI 被冻结,直到在地图上绘制矢量图层。
如何在绘图之前渲染等待面板?
我已经阅读过延迟方法,但我不太了解。
感谢您的支持。
【问题讨论】:
标签:
promise
openlayers-3
jquery-deferred
【解决方案1】:
您可能只需要强制每个阶段进入不同的事件线程,这可以通过多种方式实现。
使用window.setTimeout()
这很简单,尽管语法丑陋,但应该可以工作。
$("input#drawAllRoutes").click(function (e) {
console.log("drawAllRoutes: Start Drawing");
showWaitPanel(); // assumed to be synchronous.
window.setTimeout(function() {
...
//foreach routeElement add vector layer on map
...
hideWaitPanel(); // ok in same event thread unless vector rendering is itself asynchronous.
console.log("drawAllRoutes: Ok");
}, 0); // even with a timeout of zero seconds, the passed function will execute in a later event thread.
});
使用承诺
这里的 nett 效果应该和使用setTimeout() 非常相似,但是只有showWaitPanel() 返回一个promise 时才会起作用,否则showWaitPanel().then() 会抛出错误。所以你需要修改你的showWaitPanel() 函数。
$("input#drawAllRoutes").click(function (e) {
console.log("drawAllRoutes: Start Drawing");
showWaitPanel().then(function() {
...
//foreach routeElement add vector layer on map
...
hideWaitPanel(); // ok in same event thread unless vector rendering is itself asynchronous.
console.log("drawAllRoutes: Ok");
});
});
TBH,在这里使用承诺是矫枉过正的。如果它有效,我会使用setTimeout(),尽管它很丑。