清除JavaScript调用堆栈

时间:2016-06-23 11:51:35

标签: javascript backbone.js callstack

由于我不清楚发生了什么,我制作了一段视频:

https://vimeo.com/171929645

正如您所看到的那样,该工具在结束时崩溃,之前它只是滚动并显示每个touchevent的接触点(动画圆圈)。我只想清除堆栈,这样就不会发生了。

我正在为触摸屏电脑构建一个非常慢的JavaScript工具。这么慢,当你用手在短时间内触发100多次触摸事件(比如1秒钟)时,计算机开始逐个执行每个触摸事件。

由于执行一个touchevent已经需要几百毫秒,因此工具大约一分钟不可用。

我已经编写了这个脚本以阻止更多的触摸事件

'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;

这仍然无法阻止足够的事件,因为我的工具仍然很容易过载。

有没有办法清空整个callstack,这样我的机器就不会连续执行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多次触摸。移动您的手将触发数千次触摸事件,这将完全导致我的计算机崩溃。我怎样才能防止这种情况发生?

编辑2

其中一位说话者说'你可以忽略大部分事件。'事实并非如此。当数以千计的事件被调用时,我的计算机崩溃了,所以我不能“忽略”它们。

这个问题的重点是让我的电脑不会崩溃。每个touchstart都有多个功能可以监听它,因此每个touchstart事件都会执行多个功能。

由于这些函数需要几百毫秒才能执行,因此工具会持续执行几分钟的功能,使其无法使用。

问题在于,这台计算机速度很慢,以至于他只是“记住”所有已经输入的触摸事件,即使你在一分钟之前做过这件事,而且还在忙于其他事情。所以你只看到工具滚动,而没有人触摸屏幕。

如果仍然不清楚发生了什么,我会记录下来并将其上线。

2 个答案:

答案 0 :(得分:1)

您可以忽略大多数事件。 聚合数组中的所有相关触摸事件,然后调用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);

read more

答案 1 :(得分:0)

尝试使用debounce,它每X ms只调用一次函数。 immediate在X ms之前执行函数的第一次调用,在X ms过去之后立即调用它。

这是它的实现:



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);
&#13;
&#13;
&#13;