如何在异步回调函数中引用父级的“this”,如下面的代码片段那样?
var imaginaryAjaxCall = function (fn) {
setInterval(fn, 1000);
}
function parent() {
this.foobar = "foo";
imaginaryAjaxCall(function() {
this.foobar = "bar";
});
}
这是一个用于测试的jsfiddle:http://jsfiddle.net/r0ueon53/11/
修改 我赶紧把问题搞砸了。很抱歉,这些评论与此修改无关。
答案 0 :(得分:2)
Javascript在单个线程上运行。当您设置fn
以间隔运行时,您访问了以异步方式运行的DOM Api(即使它实际上不是异步的。)会发生什么是DOM api会将回调插入回调队列每次interval
通过。因此,每隔0ms(嗯,它实际上接近4ms,但这是另一个主题)fn
将被插入回调队列。
现在,回调队列中的回调仅在callstack为空时运行,因此,回调直到
之后才会运行document.getElementById('out').innerHTML = this.foobar;
运行,这就是输出“foo”而不是“bar”的原因。
http://jsfiddle.net/r0ueon53/13/
如果你将该行延迟一秒,你会看到它输出“bar”。
setTimeout(function () {
document.getElementById('out').innerHTML = that.foobar;
}, 1000);
http://jsfiddle.net/r0ueon53/12/
这是有效的,因为setTimeout
将在1秒后将其回调插入回调队列,因此在将值更改为“bar”的setInterval回调之后。
显然,在处理ajax时,由于网络速度的差异,使用setTimeout修复此问题并不一致。您应该只将.innerHTML移动到传递给ajax调用的回调中。