为什么这段代码不是同步执行的?
Why isn't this code executing synchronously?
我的印象是所有 DOM 操作都是同步的。
但是,此代码并不像我预期的那样 运行。
RecordManager.prototype._instantiateNewRecord = function(node) {
this.beginLoad();
var new_record = new Record(node.data.fields, this);
this.endLoad();
};
RecordManager.prototype.beginLoad = function() {
$(this.loader).removeClass('hidden');
};
RecordManager.prototype.endLoad = function() {
$(this.loader).addClass('hidden');
};
Record
构造函数非常大,它涉及实例化一大堆 Field
对象,每个对象实例化它们自己的一些其他对象。
这会导致 1-2 秒的延迟,我希望在此延迟期间有一个加载图标,这样页面就不会看起来像冻结了。
我预计事件的流程是:
- 显示加载图标
- 执行记录实例化操作
- 隐藏加载图标
除了流程最终是:
- 执行记录实例化操作
- 显示加载图标
- 隐藏加载图标
所以,你根本看不到加载图标,我只知道它正在加载,因为 chrome 开发工具 DOM 查看器的更新有点滞后。
我应该从我的代码中期待这种行为吗?如果是,为什么?
是的,这是意料之中的。尽管 DOM 可能已经更新,但在浏览器有机会重新绘制之前,您不会看到它。重绘将以与所有其他事物在浏览器中排队相同的方式排队(即它不会发生,直到 JavaScript 的当前块完成执行),尽管在调试器中暂停通常会允许它发生.
对于您的情况,您可以使用 setTimeout
立即超时修复它:
RecordManager.prototype._instantiateNewRecord = function(node) {
this.beginLoad();
setTimeout(function() {
var new_record = new Record(node.data.fields, this);
this.endLoad();
}, 0);
};
这将允许在执行代码的下一部分之前进行重绘。
JavaScript 总是同步的。当涉及到 ajax 调用和计时器时,它 模仿 多线程行为,但是当回调返回时,它将像往常一样阻塞。
就是说,您很可能在某个构造函数中有一个 setTimeout
(或者您正在使用的方法)。即使是 setTimeout(fnc, 0)
.
我的印象是所有 DOM 操作都是同步的。
但是,此代码并不像我预期的那样 运行。
RecordManager.prototype._instantiateNewRecord = function(node) {
this.beginLoad();
var new_record = new Record(node.data.fields, this);
this.endLoad();
};
RecordManager.prototype.beginLoad = function() {
$(this.loader).removeClass('hidden');
};
RecordManager.prototype.endLoad = function() {
$(this.loader).addClass('hidden');
};
Record
构造函数非常大,它涉及实例化一大堆 Field
对象,每个对象实例化它们自己的一些其他对象。
这会导致 1-2 秒的延迟,我希望在此延迟期间有一个加载图标,这样页面就不会看起来像冻结了。
我预计事件的流程是:
- 显示加载图标
- 执行记录实例化操作
- 隐藏加载图标
除了流程最终是:
- 执行记录实例化操作
- 显示加载图标
- 隐藏加载图标
所以,你根本看不到加载图标,我只知道它正在加载,因为 chrome 开发工具 DOM 查看器的更新有点滞后。
我应该从我的代码中期待这种行为吗?如果是,为什么?
是的,这是意料之中的。尽管 DOM 可能已经更新,但在浏览器有机会重新绘制之前,您不会看到它。重绘将以与所有其他事物在浏览器中排队相同的方式排队(即它不会发生,直到 JavaScript 的当前块完成执行),尽管在调试器中暂停通常会允许它发生.
对于您的情况,您可以使用 setTimeout
立即超时修复它:
RecordManager.prototype._instantiateNewRecord = function(node) {
this.beginLoad();
setTimeout(function() {
var new_record = new Record(node.data.fields, this);
this.endLoad();
}, 0);
};
这将允许在执行代码的下一部分之前进行重绘。
JavaScript 总是同步的。当涉及到 ajax 调用和计时器时,它 模仿 多线程行为,但是当回调返回时,它将像往常一样阻塞。
就是说,您很可能在某个构造函数中有一个 setTimeout
(或者您正在使用的方法)。即使是 setTimeout(fnc, 0)
.