XMLHttpRequest 和绑定回调不起作用

XMLHttpRequest and Binding a Callback not working

我有一个简单的 get 函数,它使用 XMLHttpRequest 接受回调参数。计划是在 onload 事件处理程序上调用回调。

这是一个简化版本:

get(url,doit);

function doit(data) {
    alert(data)
}
function post(url,callback) {
    var xhr=new XMLHttpRequest();
    xhr.onload=function() {                     //  Version 1
        callback(xhr.response)
    }
    xhr.onload=callback.bind(xhr,xhr.response); //  Version 2
    xhr.open('get',url,true);
    xhr.send(data);
}

回调函数有一个参数,data,应该是 Ajax 调用的响应。

我有两个调用回调的版本:

  1. 版本 1 只是在事件处理函数中调用回调。
  2. 版本 2 使用 bind 做同样的事情; this 设置为 xhr 对象,而 xhr.response 作为参数发送。

当我使用版本 1 时,一切都按预期工作。当我使用版本 2 时,data 参数为空。

我以为我对 XMLHttpRequest.bind() 相当了解,但我不知道为什么第二个版本是空的。这里发生(未)发生什么?

评论

多亏了大家的回答,我想我知道了。

.bind() 立即执行 currentxhr.responseText,在这个阶段什么都没有。

如果我需要用 future 值进行响应,那么第一个版本似乎更可取。

谢谢大家。

因为callback.bind会被立即执行。并且在执行时,xhr.responseText 显然不可用,因为请求尚未完成。你可以试试看效果。

function doit(data) {
    alert(data, this.responseText);
}

这是bind的行为:绑定参数时,绑定的值是被引用的对象,或者是当时的原始值。

这是一个简单的代码片段:

function operate(callback) {
  let a = {
    display: 'AAA'
  };
  setTimeout(callback.bind('ThisObj', a.display), 1000);
  a.display = 'AAA222';
}

operate(function(data) {
  console.log(data);
});

打印结果为:AAA,因为a.display是绑定的,a.display是原始类型(String)——绑定时刻的值(AAA) 通过。

这正是 xhr.response 发生的情况,因为它的类型是字符串。


然而,如果一个对象被绑定为参数,该对象的引用将被传递,这意味着绑定函数将获得最新值:

function operate(callback) {
  let tmp = {
    t: 'AAA'
  };
  let a = {
    display: tmp
  };
  setTimeout(callback.bind('ThisObj', a.display), 1000);
  tmp.t = 'AAA222';
}

operate(function(data) {
  console.log(data);
});

打印结果为:{ t: 'AAA222' }

请注意:如果上例中的变量a将其值更改为另一个对象,绑定的引用值不会改变(仍然是之前引用的对象):

function operate(callback) {
  let a = {
    display: 'AAA'
  };
  setTimeout(callback.bind('ThisObj', a), 1000);
  a = {
    display: 'AAA222'
  };
}

operate(function(data) {
  console.log(data);
});

打印结果为:{ display: 'AAA' }