我无法解决范围问题。实际上我正在开发一个HMI浏览器前端的项目。它应该可视化自动化系统中的变量。对于HMI,要求用户可以在不同页面之间切换。为了解决一般的流程,我创建了一个状态机功能,它协调加载,绘图和与用户的交互。我现在的问题是我使用setTimeout来调用run函数(实际上是我的状态机),现在运行var-scope。
请看以下代码:
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();
}
问题是run-Function中的范围。如果从构造函数结束第一次调用,一切都可以。 run可以访问所有私有属性并操纵它们。但是当稍后通过m_continue中的setTimeout或自身调用它时,我无法访问私有属性。在萤火虫中,我只能看到公共属性和功能,而不是我需要的私有属性。
使用全局变量会有所帮助,但是不可能,因为在多监视器解决方案中,我有2个独立的画布对象,需要显示HMI的分离版本 - 对于这种情况,我需要2个并行运行的前端实例浏览器窗口。
有没有人知道这个问题的解决方案?我的知识结束了,完全糊涂了。
答案 0 :(得分:1)
最简单的方法是定义你的范围。任何许多renound javascript库也使用这种技术。
this.m_continue = function() {
that = this;
if (runWait) {
runWait = false;
setTimeout(that.run, 100);
}
}
否则您也可以使用apply
答案 1 :(得分:0)
您应该绑定每个setTimeout中的run函数,因为run使用this
。
setTimeout(run.bind(this), 100);