清除JavaScript调用堆栈
由于我不清楚发生了什么事我做了一个视频:
https://vimeo.com/171929645
正如你可以看到该工具在最后崩溃,在此之前它只是滚动并显示每个触发事件的接触点(动画圈)。 我只是想清除堆栈,所以这不会发生。
我正在为非常缓慢的触摸屏计算机构建JavaScript工具。 这么慢,当你在少量时间(比如1秒)使用你的手触发100多个触发器时,计算机开始执行每个触摸事件。
由于执行一次touchevent已经花费了几百毫秒,所以该工具在大约一分钟内不可用。
我已经写了这个脚本阻止了很多touchevents
'use strict';
var MultiTouch = Backbone.NativeView.extend({
el: document,
initialize: function () {
console.log('Init MultiTouch');
this.el.addEventListener('touchstart', function(e) {
this.touchstartHandler(e);
}.bind(this));
},
touchstartHandler: function (e) {
if (this.block) {
console.log("block");
e.preventDefault();
e.stopPropagation();
e.stopImmediatePropagation();
return;
}
console.log("no block");
this.startTimer();
},
startTimer: function () {
this.block = true;
setTimeout(function () {
this.block = false;
}.bind(this), 300);
}
});
module.exports = MultiTouch;
这仍然不能阻止足够的事件,因为我的工具仍然过载很容易。
有没有办法清空整个调用堆栈,以便我的机器不会连续执行100多个函数?
谢谢。
编辑
我稍微更新了脚本并添加了两个控制台日志。 这是我将手放在触摸屏上时所得到的结果:
no block MultiTouch.js:31
17 block MultiTouch.js:23
no block MultiTouch.js:31
19 block MultiTouch.js:23
no block MultiTouch.js:31
12 block MultiTouch.js:23
no block MultiTouch.js:31
20 block MultiTouch.js:23
no block MultiTouch.js:31
7 block MultiTouch.js:23
no block MultiTouch.js:31
8 block MultiTouch.js:23
no block MultiTouch.js:31
6 block MultiTouch.js:23
no block MultiTouch.js:31
9 block MultiTouch.js:23
2 no block MultiTouch.js:31
9 block MultiTouch.js:23
no block MultiTouch.js:31
7 block MultiTouch.js:23
no block MultiTouch.js:31
5 block MultiTouch.js:23
no block MultiTouch.js:31
7 block MultiTouch.js:23
no block MultiTouch.js:31
6 block MultiTouch.js:23
no block MultiTouch.js:31
11 block MultiTouch.js:23
no block MultiTouch.js:31
3 block MultiTouch.js:23
因此,将一只手放在屏幕上会触发更多170次触发事件。 移动你的手将触发成千上万的touchevent,这将完全崩溃我的电脑。 我怎样才能防止这种情况发生?
编辑2
其中一位矿主说:“你可以忽略大部分事件。” 情况并非如此。 当数以千计的事件被称为我的电脑崩溃,所以我不能'忽略'他们。
这个问题的整个观点是让我的电脑不会崩溃。 每个touchstart都有多个函数在监听,所以每个touchstart事件都会执行多个函数。
由于这些功能需要几百毫秒才能执行,因此该工具会持续执行几分钟的功能,使其无法使用。
问题在于,这台电脑太慢了,以至于他只记得所有的输入内容,即使你在一分钟之前完成了这个操作,并且仍然忙于其他内容。 所以你只需看到该工具在没有人触摸屏幕时自动滚动。
如果还不清楚发生了什么,我会记录下来并将其放到网上。
你可以忽略大部分事件。 在Array中聚合所有相关的触摸事件,然后调用startHandler()
。 例如,您可能只需要第一个和最后一个事件:
touchstartHandler: function (e) {
this.events.push(e)
this.startTimer();
},
由于您使用Backbone,因此您可以尝试使用_.debounce
或_.throttle to limit calling
startHandler()``次数太多。
startTimer: _.debounce(function () {
//do sth with this.events
console.log(this.events[0])
}, 50);
_.debounce()文档
尝试使用debounce,每X毫秒只调用一次函数。 立即在Xms之前执行第一个函数调用,在Xms之后非立即调用它。
这里是它的实现:
function debounce(func, wait, immediate) {
var timeout;
return function() {
var context = this,
args = arguments;
var later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
};
var touchEvent = function() {
console.log('touched');
};
var debouncedTouchEvent = debounce(touchEvent, 500, true);
for (var i = 0; i < 100000; i++) {
debouncedTouchEvent();
//will only be called once every 500ms.
}
// element.addEventListener('touch', debouncedTouchEvent);
链接地址: http://www.djcxy.com/p/71695.html
上一篇: Clear JavaScript call stack
下一篇: jQuery: Too Much Recursion and Maximum Call Stack Size Exceeded