jQuery中.load()与.on()内AJAX获取值不一致问题求助
问题根源:AJAX的异步执行顺序
这问题我太熟了,本质就是AJAX的异步特性在搞鬼!咱们先拆解下你遇到的场景:
你应该是在代码里先预定义了var total_posts = 9999999,然后同时发起了两个异步操作:一个是用.load()加载内容到#container,另一个是从total_posts.php获取真实的total_posts值。
AJAX请求是异步非阻塞的,也就是说这两个请求会同时跑,谁先完成完全看服务器响应速度。大概率你的.load()请求先完成了,这时候获取total_posts的请求还没返回结果,所以回调里的alert(total_posts)只能拿到最初的预定义值9999999。
而当你点击.more触发事件时,距离页面初始化已经过了一段时间,获取total_posts的请求早就完成了,变量已经被更新成真实值,所以alert就能显示正确结果。
举个你可能的代码结构例子,一看就懂:
var total_posts = 9999999; // 异步获取真实total_posts $.get('total_posts.php', function(data) { total_posts = data; // 这个回调可能在.load回调之后执行 }); // 首次加载内容 $('#container').load('content.php', function() { alert(total_posts); // 此时上面的$.get还没跑完,所以是9999999 }); // 点击加载更多 $(document).on('click', '.more', function() { $('#container').load('more_content.php', function() { alert(total_posts); // 这时候$.get早就完成了,值正确 }); });
解决办法
根据你的需求,有几种靠谱的方案:
方案1:先拿total_posts,再加载内容
把内容加载的操作放在获取total_posts的回调里,保证顺序:
var total_posts = 9999999; // 先获取真实值,再加载内容 $.get('total_posts.php', function(data) { total_posts = data; $('#container').load('content.php', function() { alert(total_posts); // 现在肯定是正确值 }); }); $(document).on('click', '.more', function() { // 点击时可以重新获取一次(防止数值变化),再加载 $.get('total_posts.php', function(data) { total_posts = data; $('#container').load('more_content.php', function() { alert(total_posts); }); }); });
方案2:在.load回调里获取total_posts
如果total_posts可能随着内容更新而变化,每次加载内容后都重新获取:
var total_posts = 9999999; function loadAndUpdate() { $('#container').load('content.php', function() { // 内容加载完再拿最新的total_posts $.get('total_posts.php', function(data) { total_posts = data; alert(total_posts); }); }); } // 首次执行 loadAndUpdate(); // 点击事件复用函数 $(document).on('click', '.more', loadAndUpdate);
方案3:用Promise管理异步流程(更优雅)
适合复杂的异步场景,让代码逻辑更清晰:
// 封装获取total_posts的Promise function getTotalPosts() { return new Promise(resolve => { $.get('total_posts.php', data => resolve(data)); }); } // 封装加载容器的Promise function loadContainer() { return new Promise(resolve => { $('#container').load('content.php', () => resolve()); }); } // 首次加载:先拿值,再加载内容 getTotalPosts().then(total => { total_posts = total; return loadContainer(); }).then(() => { alert(total_posts); }); // 点击加载更多 $(document).on('click', '.more', () => { getTotalPosts().then(total => { total_posts = total; return loadContainer(); }).then(() => { alert(total_posts); }); });
内容的提问来源于stack exchange,提问作者joe
相关产品推荐
相关产品推荐

