ajax返回值为undefined
刚开始学ajax,在一个项目中会多次向后台发送请求,通过get方式请求时的参数相同,就打算封装一个ajax请求函数,调用就很方便,但是用老方法原生封装时,返回值一直会是undefined,就算是全局变量,甚至是windows的一个属性接收传回来的数据,都是undefined。
//api为接口地址
function getFunction(api){
var information = {}
var xhr8 = new XMLHttpRequest()
xhr8.open('GET','http://'+api+'?userId='+userId,true)
xhr8.send()
xhr8.onreadystatechange = function(){
if(xhr8.readyState === 4 &&xhr8.status === 200){
console.log(xhr8.responseText);
information = JSON.parse(xhr8.responseText)
console.log('----');
console.log(information);
console.log('----');
return information
// return xhr8.responseText
console.log(1)
}
}
console.log(2)
}
var jkl = getFunction('...',)
console.log(jkl);//undefined
在接受数据中,是可以打印处information,且information就是接收到的返回值,但是一返回,就是外部接收者的初始值,undefined或{}。
可能有人会发现,return放在内部函数里,返回值不就是返回到 xhr8.onreadystatechange里了吗?
所以我把它又放到getFunction里最后一行,还是同样的结果。感到很崩溃。
搜索了一下,有答案说是同步异步问题,改了也是同样的结果。
同步异步给了启发,用两个控制台输出看一下输出顺序,惊喜发现是先打印2再打印1。其实这是因为事件总是被排在线程的最后,就是全部语句执行完再执行事件,就导致了接受返回数据这个事件最后才发生,而返回值已经返回到函数调用处,在反过来接受数据,所以传回去的值是undefined或是变量初始值。
所以这个方法是行不通的,所以后来用promise去再内部包装,解决异步的问题
还有点小问题,就是一开始再resolve函数是没有转换json格式,所以传参不成功,也会undefined,还以为是同一个bug,😭
function getFunction(api){
const p = new Promise((resolve,reject)=>{
//1.创建xhr对象
const xhr8 = new XMLHttpRequest();
//2.初始化
xhr8.open('GET','http://'+api+'?userId='+userId,true)
//3.发送
xhr8.send();
xhr8.onreadystatechange = function () {
if (xhr8.readyState === 4) {
if (xhr8.status == 200) {
resolve(JSON.parse(xhr8.responseText));
} else {
reject()
}
}
};
})
p.then(
function (value) {console.log(value.data);},
function (reason) {console.error(reason);}
);
console.log(information)//undefined
}
这里其实也不能用如果控制台打印也是undefined,因为直接用console.log会先执行,所以就先打印出undefined,再进行发送请求的事件,其实全局变量以及储存了,但是先打印的是空的,试试直接调用的时候能不能得到吧。或者进行的操作再then方法里直接执行。