csdn很少上线,经常在掘金摸鱼,本文掘金链接https://juejin/post/7058602557987356708
言归正传:
如果我想将ajax封装在一个具名函数中,然后用这个具名函数返回ajax获得的数据,能直接成功吗?
答案是不可以的,因为在js中ajax默认是异步的,而具名函数是同步的,先于ajax执行,所以无法获得ajax获得的数据,最终的结果就是undefined。
需求:
随机生成一个10位数的整数,与后端数据库做对比,如果后端数据库中有这个随机数,则重新再生成一个,如果没有就return这个数。
这个需求涉及到前后端交互,所以无法避免需要使用ajax,于是刚开始我编写了这样一段代码。
//randID是封装的生成随机数的函数
function userID() {
let ranid = parseInt(randID(1000000000, 10000000001));
let data = null;
$.ajax({
type: 'post',
url: './php/findID.php',
data: 'id=' + ranid,
success: function(res) {
res = JSON.parse(res);
isok = res.length;
if (isok != 0) {
userID();
} else {
return ranid;
}
}
})
}
console.log(userID());
最终执行结果:
小小白的我发现ajax接收的结果没有被返回,顿时陷入了沉思,一开始以为是自己代码出了问题,不过我经常和朋友说‘没法解释的问题,都归咎于异步’(这是一句玩笑话),所以,没一会就知道这是js同步异步在作祟,问题明确了,那么我要怎么将原本异步的ajax变成和具名函数一样同步执行的呢?
jquery.ajax的解决方法
- 在函数下(ajax外)声明一个局部变量
- 将ajax当成同步处理(jquery.ajax的修改方式:添加这句代码即可
async: false
) - 返回声明的局部变量
function userID() {
let ranid = parseInt(randID(1000000000, 10000000001));
//声明的局部变量
let data = null;
$.ajax({
type: 'post',
url: './php/findID.php',
data: 'id=' + ranid,
//将ajax改为同步操作
async: false,
success: function(res) {
res = JSON.parse(res);
isok = res.length;
if (isok != 0) {
console.log(ranid);
userID();
} else {
data = ranid;
}
}
})
//返回这个局部变量
return data;
}
console.log(userID());
运行结果:
那么原生js怎么解决ajax同步呢?
解决步骤:
- 将open函数的第三个参数,设置为false。(true代表异步,false代表同步)
- 获取后端数据不在使用onload事件
- 直接返回需要的数据
同一需求(原生js ajax代码)
function ajax() {
let ranids = parseInt(randID(1000000000, 10000000001));
const xhr = new XMLHttpRequest();
xhr.open('post', './php/findID.php', false);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send('id=' + ranids);
let resData = JSON.parse(xhr.responseText);
if (resData.length != 0) {
ajax();
} else {
return ranids;
}
}
console.log(ajax());
执行结果
如果我的这篇文章对您有帮助,请施舍一个赞吧!如果您有更多更好的解决方式,欢迎您来掘金评论区指教。
更多推荐
将AJAX转换为同步,原来这么简单
发布评论