简体   繁体   English

“类”内的JavaScript范围和setTimeout

[英]JavaScript Scope and setTimeout inside of a “class”

I have trouble to solve a scope issue. 我很难解决范围问题。 Actually I'm working on a project for an HMI browser frontend. 实际上,我正在为HMI浏览器前端项目。 It's should visualise variables from an automation system. 它应该可视化自动化系统中的变量。 For the HMI it's required that the user can switch between different pages. 对于HMI,要求用户可以在不同页面之间切换。 To solve the general process flow I have created a state machine function, which coordinates loading, drawing and interaction with user. 为了解决一般流程,我创建了一个状态机功能,该功能可以协调加载,绘制以及与用户的交互。 My problem now is that I use setTimeout to call the run function (which is actually my state machine) and now run in trouble with var-scope. 我现在的问题是,我使用setTimeout调用run函数(实际上是我的状态机),但现在在运行var-scope时遇到了麻烦。

Look at following code: 看下面的代码:

function frontend() {

  // Public properties:
  this.soundEnable = true;

  // Private Properties:
  var p1 = 0;
  var p2 = [1,2,3];
  var p3 = {a:1, b:2, c:3};
  var runState = 1;
  var runWait = false:

  // Public Methods

  // stops the state machine until m_continue is called
  this.m_wait = function() {
    runWait = true;
  }

  // continues the state machine
  this.m_continue = function() {
    if (runWait) {
      runWait = false;
      setTimeout(run, 100);
    }
  }

  // Private Methods

  function drawFrame(finish_callback) {
    ...<Drawing of HMI-Objects on the canvas>...
    finish_callback();
  }

  function run() {
    switch (runState) {
    case 1:
      this.m_stop();
      drawFrame(this.m_continue());
    case 2:
      for(i=0; i<p3.length; i++) {
        p2.push(externalObjectCreator(p3[i]));
      }
    }
    if (!runWait) {
      runState++;
      setTimeout(run, 100);
    }
  }

  // Constructor
  ...<code to assign public and private properties>...

  // Finally call the state machine to activate the frontend
  runState = 1;
  run();
}

Problem is scope in run-Function. 问题是运行功能的范围。 In case of the first call from end of constructor everything is ok. 如果从构造函数的末尾进行第一次调用,则一切正常。 run can access all the private properties and manipulate them. 运行可以访问所有私有属性并进行操作。 But when it is called later on via setTimeout from m_continue or by itself I can't access the private properties. 但是,当稍后通过setTimeout从m_continue或单独调用它时,我无法访问私有属性。 In firebug I can just see the public properties and functions and none of the private properties I need. 在Firebug中,我只能看到公共属性和功能,而没有我需要的私有属性。

Using of global variables will help, but is not possible, because on multi monitor solution I have 2 separated canvas objects which need to show a separated version of the HMI - for that case I need 2 instances of frontend running parallel in one browser window. 使用全局变量将有所帮助,但无法实现,因为在多监视器解决方案中,我有2个分离的画布对象,它们需要显示HMI的分离版本-在这种情况下,我需要2个前端实例在一个浏览器窗口中并行运行。

Does anyone know a solution for that problem? 有人知道该问题的解决方案吗? I'm on the end of my knowledge and totally confused. 我在我的知识的尽头,完全困惑。

The easiest way will be to define your scope like. 最简单的方法将是定义您的范围。 Any many renound javascript libraries also use this technique. 许多知名的javascript库也都使用此技术。

this.m_continue = function() {
 that = this;  
 if (runWait) {
      runWait = false;
      setTimeout(that.run, 100);
    }
  }

Otherwise you may also use scope binding using apply 否则,您也可以使用apply使用范围绑定

您应该在每个setTimeout中绑定run函数,因为run使用this

setTimeout(run.bind(this), 100);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM