【问题标题】:Accessing "this" in asynchronous callback function in JavaScript在 JavaScript 的异步回调函数中访问“this”
【发布时间】:2015-01-30 21:56:35
【问题描述】:

我将如何实现从异步回调函数中引用父级的“this”,例如下面的 sn-p?

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

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

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

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

编辑: 我匆忙提出这个问题,把它搞砸了。很抱歉渲染了一些与此编辑无关的 cmets。

【问题讨论】:

  • 不确定“this”的使用位置,因为它不在代码中,但请了解bind()
  • setInterval( fn, 0 ) 在运行 fn 之前等待主脚本完成,即使时间设置为零。
  • @epascarello this 在这里不是问题。它被 that = this 正确缓存。
  • 那你之前的评论就没有意义了。

标签: javascript asynchronous callback this setinterval


【解决方案1】:

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

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

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

【讨论】:

    猜你喜欢
    • 2016-07-20
    • 2023-04-04
    • 1970-01-01
    • 1970-01-01
    • 2021-04-04
    • 2015-09-14
    • 1970-01-01
    • 2017-07-19
    • 1970-01-01
    相关资源
    最近更新 更多