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 只是在事件处理函数中调用回调。
- 版本 2 使用
bind
做同样的事情; this
设置为 xhr
对象,而 xhr.response
作为参数发送。
当我使用版本 1 时,一切都按预期工作。当我使用版本 2 时,data
参数为空。
我以为我对 XMLHttpRequest
和 .bind()
相当了解,但我不知道为什么第二个版本是空的。这里发生(未)发生什么?
评论
多亏了大家的回答,我想我知道了。
.bind()
立即执行 current 值 xhr.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' }
我有一个简单的 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 只是在事件处理函数中调用回调。
- 版本 2 使用
bind
做同样的事情;this
设置为xhr
对象,而xhr.response
作为参数发送。
当我使用版本 1 时,一切都按预期工作。当我使用版本 2 时,data
参数为空。
我以为我对 XMLHttpRequest
和 .bind()
相当了解,但我不知道为什么第二个版本是空的。这里发生(未)发生什么?
评论
多亏了大家的回答,我想我知道了。
.bind()
立即执行 current 值 xhr.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' }