jQuery AJAX请求后全局变量取值为undefined问题咨询
问题根因
- 你遇到的
data.sent取值为undefined是异步请求执行顺序导致的:jQuery AJAX默认是异步执行,你调用fetchSTatus后不等接口返回结果,就直接读取senderPerson拼接输出内容,此时接口还没返回,senderPerson还未被赋值。 - 次要问题:
fetchSTatus的success回调中,return senderPerson = data.sent写在了日志打印前,后续的console.log永远不会执行,且你将返回值赋值给全局变量的方式本身也不适合异步场景。
修复方案
这里我们用Promise + async/await 来处理异步逻辑,保证拿到接口返回结果后再拼接输出内容:
第一步:改造fetchSTatus函数,让它返回请求结果的Promise
function fetchSTatus(x) { var person = new Object(); // 直接return $.ajax的返回值,它本身就是Promise对象 return $.ajax({ url: 'http://localhost:3000/friends/' + x , type: 'GET', dataType: 'json', data: person, success: function (data, textStatus, xhr) { if(data.sender == Friend1 && data.reciver == x) { console.log(data.sender); console.log(Friend1); console.log(data.reciver); console.log(x); console.log(data.sent); }; // 这里不需要给全局变量赋值,直接把结果返回即可 return data.sent; }, error: function (xhr, textStatus, errorThrown) { document.getElementById('error').style.color = 'red'; const element = document.getElementById("error"); element.innerHTML = "Error in Operation"; console.log("Error in Operation"); // 出错时默认返回false或者你需要的默认值 return false; } }); };
第二步:改造搜索逻辑,用async/await等待所有状态请求完成后再拼接输出
$(document).ready(function(){ var person = new Object(); $.ajax({ url: 'http://localhost:3000/customers/', type: 'GET', dataType: 'json', data: person, success: function (data, textStatus, xhr) { // 给keyup的回调加上async标记,支持内部用await $('#txt-search').keyup(async function(){ var searchField = $(this).val(); if(searchField === '') { $('#filter-records').html(''); return; } var regex = new RegExp(searchField, "i"); var output = '<div class="row">'; // 先过滤出符合搜索条件的用户 const matchedUsers = data.filter(val => { if(val.name === DefaultName) return false; return val.name.search(regex) != -1; }); // 并行请求所有匹配用户的好友状态,提升效率 const statusList = await Promise.all( matchedUsers.map(user => fetchSTatus(user.uuid)) ); // 遍历拼接结果,此时已经拿到了所有状态 matchedUsers.forEach((val, index) => { const senderPerson = statusList[index]; output += '<br><h5>' + val.name + '</h5>'; output += '<h5>' + val.uuid + '</h5>'; output += '<h5>' + senderPerson + '</h5>'; }); output += '</div>'; $('#filter-records').html(output); }); }, error: function (xhr, textStatus, errorThrown) { document.getElementById('error').style.color = 'red'; const element = document.getElementById("error"); element.innerHTML = "Error in Operation"; console.log("Error in Operation"); } }); });
其他优化建议
- 可以给keyup事件加防抖,避免用户连续输入时频繁发起请求,减少服务端压力
- 如果用户量较大,可以考虑把好友状态的判断合并到搜索接口里,前端不需要单独发起多次请求,性能更好
内容的提问来源于stack exchange,提问作者James
相关产品推荐
相关产品推荐

