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

Accessing "this" in asynchronous callback function in JavaScript

本文关键字:访问 this 函数 回调 JavaScript 异步      更新时间:2023-09-26

我将如何实现从异步回调函数内部引用父级的"this",如下面的代码片段所示?

var imaginaryAjaxCall = function (fn) {
    setInterval(fn, 1000);
}
function parent() {
    this.foobar = "foo";
    imaginaryAjaxCall(function() {
       this.foobar = "bar"; 
    });
}

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

编辑:我急忙问道,把它搞砸了。很抱歉使一些评论与此编辑无关。

Javascript 在单个线程上运行。当您将fn设置为按时间间隔运行时,您访问了一个以异步方式运行的 DOM Api(即使它实际上不是异步的)。发生的情况是,每次传递interval时,DOM api 都会在回调队列中插入一个回调。因此,每 0 毫秒(嗯,它实际上更接近 4 毫秒,但这是另一个主题)fn将入回调队列。

现在,回调队列中的回调仅在调用堆栈为空时运行,因此,回调直到之后才会运行

document.getElementById('out').innerHTML = this.foobar;

是 ran,这就是为什么它输出 "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 调用的回调中。