在JavaScript中访问异步回调函数中的“this”

时间:2015-01-30 21:56:35

标签: javascript asynchronous callback this setinterval

如何在异步回调函数中引用父级的“this”,如下面的代码片段那样?

var imaginaryAjaxCall = function (fn) {
    setInterval(fn, 1000);
}

function parent() {
    this.foobar = "foo";

    imaginaryAjaxCall(function() {
       this.foobar = "bar"; 
    });
}

这是一个用于测试的jsfiddle:http://jsfiddle.net/r0ueon53/11/

修改 我赶紧把问题搞砸了。很抱歉,这些评论与此修改无关。

1 个答案:

答案 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调用的回调中。