我有一个select
元素change
事件的侦听器:在更改时,会获取一个文件并计算一个复杂的 SVG 并将其加载到 DOM(读取:需要相当数量的 CPU 周期)。问题是,如果您select
非常快速地更改(通过编码的键盘快捷键),则会将多个内容加载到 SVG 容器中——我一次只希望加载一个。为了解决这个问题,我做了这个(半伪):
select.on("change", function() { queue(this.val); });
var queuedFile, state = "ready";
function queue(file) {
queuedFile = file;
// NB: in real code, queuedFile is a property and the getter empties the queue
if (state === "ready") { loadFile(queuedFile); }
}
function loadFile(file) {
state = "busy";
ajaxGet(file, function(result) {
// lots of statements, iterators, calls to other fns
state = "ready";
// NB: again in real code the getter empties the queue
var qf = queuedFile;
if (qf) { clearSVG(); loadFile(qf); }
}); // end ajaxGet
}
也就是说:在select
更改时,将新文件排队,如果文件加载器不忙于加载另一个文件,则加载它,否则什么也不做。文件加载器完成后,如果有排队文件,则清除 SVG 并加载排队文件。似乎这一次应该只允许 SVG 容器中的一个文件。
实际上,state
永远不会"busy"
在签入时queue()
,所以我仍然将多个文件加载到 SVG 中。不过,console.log(state)
紧随其后的state = "busy"
演出"busy"
。我在这里想念什么?我不认为这是范围的问题queuedFile
。
为了完整起见,我的队列属性是这样的:
// given: all of this code is enclosed in a function that returns an object "viewer".
// (only one instance of the "viewer" is created)
Object.defineProperty(viewer, "queuedFile", {
get: function () {
console.log("dequeuing", this.filequeue);
var buffer = this.filequeue;
this.filequeue = null;
return buffer;
},
set: function (newval) {
console.log("queuing", newval);
this.filequeue = newval;
}
});