我正在异步接收数据(每秒0到100个点),该数据传递给启动成本很高的函数extendTraces(data),该函数会更新用户界面。如果在生成每个点时调用extendTraces(),则用户界面将变得无响应。我发现定期调用该函数并将其传递给点数组(称为pointArray)会更加高效。
我可以跟踪添加到pointArray的点数,并每添加20个就调用extendTraces(pointArray):
//inside asynchronous function
pointArray.push(point);
if (this.pointArray.length == 20){
(<any>Plotly).extendTraces(this.pointArray);
this.resetPointArray();
}
但是,如果我将pointArray填满了一半并且一阵子没有收到任何数据,我也将调用extendTraces。
我的解决方案是每秒调用一次extendTraces()
//inside a function that is called when the page loads
window.setInterval(function() {
if (pointArray.length > 0){
(<any>Plotly).extendTraces(this.pointArray);
this.resetPointArray();
}
}, 1000);
我接收点的函数会将它们简单地连接到pointArray上。
//inside asynchronous function
pointArray.push(point);
我是JS新手,想知道我是否为此任务使用了正确的范例。我看到了很多关于回调和Promise的信息,这些信息我还不太了解,但是我怀疑自己没有使用它们在做错事。来自c ++,我担心两个函数(在setInterval中定义的函数和接收点的异步函数)都可以访问pointArray而没有任何硬编码的互斥体。
答案 0 :(得分:1)
您应该创建一个反跳功能,这基本上限制了该功能的调用频率。这是下划线库中的去抖动功能:
this.state.previousMarker.infowindow = false
现在,只需将您的extendTraces函数包装在debounce函数周围,然后调用从其返回的函数即可。
来源:https://github.com/jashkenas/underscore/blob/master/underscore.js#L887-L914
答案 1 :(得分:1)
我很想将逻辑包装到自己的类中,该类只允许您指定
function PointHandler(flushSize, flushTime, flushCallback){
var pointArray = [];
var lastFlush = setTimeout(() => this.flush(),flushTime)
this.addPoint = function(point){
pointArray.push(point);
if(pointArray.length == flushSize){
this.flush();
}
clearTimeout(lastFlush)
lastFlush = setTimeout(() => this.flush(), flushTime);
}
this.flush = function(){
flushCallback(pointArray);
pointArray = [];
clearTimeout(lastFlush)
lastFlush = setTimeout(() => this.flush(), flushTime);
}
}
var handler = new PointHandler(10, 5000, points => console.log(points));
document.getElementById("clickme").addEventListener("click", () => handler.addPoint(new Date()));
<button id="clickme">Add point</button>
以上代码将在闲置5秒钟或添加10点后调用回调。
我的回调仅console.log
当前点,但是您可以调用您的方法。