javascript - 将对象参数传递给setInterval
我已经编程了几年,但我是JavaScript新手。我试图创建一个标准线程'通知'功能的hacky版本。我正在运行一系列ajax数据请求,每个请求需要大约200毫秒才能执行,并且我需要等到它们全部完成后再执行一个操作(绘制图形)。javascript - 将对象参数传递给setInterval
我的解决方案是让每个线程在完成时增加一个全局变量。然后,我使用setTimeout创建了一个计时器,每隔100毫秒检查一次,看看是否所有线程都更新了变量,并且如果他们有,则执行该操作。
尽管有点哈克,这工作。
快进未来的几个星期,我的程序不断增加,现在我们需要的是 能够在同一页面上有多个图表,每个图表使用上述ajax请求独立管理其数据,如以及使用图形的几个不同页面。因此,我将图形代码提取到带有require.js的模块中,并定义一个执行图形化的类来隔离每个图形与其他图形,但突然间setInterval不起作用。我做了一些谷歌搜索,找到下面的文章,我有点明白...
所以无论如何看来,当使用setInterval的“本”成为一些奇怪的原因的窗口,因此,看不到我的方法。
无论如何,我试图创造一个变种研究所遏制“这个”明确,这似乎帮助,但由于某些原因,它不喜欢过客“出师表”作为递归调用的参数。从Firebug控制台该错误消息是这样的:
失踪]后元素列表 [打破此错误]
}(9.9,[对象的对象))
下面是从一个样品我的代码:
var inst = this;
// some code... then in a function...
function(){
inst.waitUntil(10, inst);
}
inst.waitUntil = function(how_many_seconds, inst){
if (how_many_seconds < 0){
alert("Script timed out.");
return;
} else {
if (inst.allSchoolsLoaded()){
setTimeout("("+inst.draw+"("+inst.after+"))", 100);
} else {
var argString = "("+inst.waitUntil+"("+(how_many_seconds-0.1)+", "+inst+"))";
//alert(argString);
setTimeout(argString, 100);
}
}
}
你可以假设所有提到的变量都是在类的前面定义的。
我在束手无策我在这里,任何帮助将非常感激。如果任何人都可以建议线程问题是可以避免的setInterval完全,这将是真棒更好的解决办法,否则,如果你能提出一个办法让setInterval的工作或替代功能,这将是巨大的。
jQuery可用,我不介意安装其他工具,如果他们会帮助。
提前许多感谢,
亚历
您正试图创建一个对象的字符串。对象的标准字符串表示形式为[object Object]
。你可能也会有问题inst.waitUntil
,因为它转化为函数的字符串表示(在某些(大多数?)的浏览器功能的源)。
而不是创建一个字符串,只是通过一个函数来setTimeout
:
setTimeout(function() {
inst.waitUntil(how_many_seconds-0.1, inst);
}, 100);
现在,里面waitUntil
,this
将参考inst
。鉴于此,您可能能够进一步简化您的代码。
例如:
this.waitUntil = function(how_many_seconds){
var self = this;
if (how_many_seconds < 0){
alert("Script timed out.");
return;
} else {
var callback = function() {
self.waitUntil(how_many_seconds-0.1);
};
if (this.allSchoolsLoaded()){
callback = function() {
self.draw(self.after);
};
}
setTimeout(callback, 100);
}
};
:-)我们写了同样的东西,很抱歉,但我喜欢只有一个setTimeout更多,很好! – 2012-02-24 01:38:26
我记得在因特网上寻找setTimeout的例子,由于某些原因,他们没有证明你可以传递一个函数,所以我犯了和Alex一样的错误。希望我已经知道堆栈溢出,然后得到这样的答案。 ;-) – 2012-02-24 01:47:13
对,我想我很困惑,并认为setInterval总是将'this'设置为'window'...非常感谢您的帮助:) – Alex 2012-02-24 06:25:19
不要使用字符串,它使用eval
内部和它的坏为您的代码的性能和可维护性。取而代之的是:
if (inst.allSchoolsLoaded()){
setTimeout("("+inst.draw+"("+inst.after+"))", 100);
} else {
var argString = "("+inst.waitUntil+"("+(how_many_seconds-0.1)+", "+inst+"))";
//alert(argString);
setTimeout(argString, 100);
}
这样做:
if (inst.allSchoolsLoaded()){
setTimeout(function() {
inst.draw(inst.after);
}, 100);
} else {
setTimeout(function() {
inst.waitUntil(how_many_seconds - 0.1);
}, 100);
}
而且,你不需要通过inst
如果你正在使用的实例waitUntil
方法,this
背景将被设定为inst
本身,因此:
inst.waitUntil = function (seconds) {
// `this` is now pointing at `inst`
// we will cache a reference to the object into a variable
// because anonymous function will have its own context (`this`)
// in the link provided in comment you can see alternatives such as using
// ECMAScript `bind` Function method to bind function context to certain object
var self = this;
if (seconds < 0) return alert('timeout');
if (inst.allSchoolsLoaded()){
setTimeout(function() {
self.draw(self.after);
}, 100);
} else {
setTimeout(function() {
self.waitUntil(seconds - 0.1);
}, 100);
}
};
感谢您的帮助:) – Alex 2012-02-24 06:48:30
张贴在这里的解决方案工作完美,谢谢你的帮助。
万一别人也有类似的需要执行多个AJAX请求,其实我偶然发现了一个jQuery的方法处理此优雅:
http://api.jquery.com/jQuery.when/
它可能需要几个“递延”对象,包括AJAX请求,并等待它们全部成功执行或其中一个失败。使用这个,我可以完全摆脱我的setInterval计时器。
干杯,
亚历
那么,什么是错'VAR completedCalls = 0;函数ajaxThreadResult(){... completedCalls ++; }'然后检查'completedCalls == callsMade'? – 2012-02-24 01:24:04
看到这个问题,并在那里回复:http://stackoverflow.com/questions/2130241/pass-correct-this-context-to-settimeout-callback/9298306#9298306 – 2012-02-24 01:24:11
是的,这实际上是我在做什么...函数allSchoolsLoaded()只是测试completedCalls == callsMade(显然具有不同的变量名称)。问题是如何每隔一段时间检查一下这个状态...... – Alex 2012-02-24 06:27:41