如何在不使用async:false的情况下为Ajax中的全局变量赋值?
如何在不使用
async:false的前提下为Ajax请求中的全局变量赋值 首先得明确:Ajax默认是异步操作,这意味着代码不会等待请求完成就继续执行。所以直接在Ajax外面赋值全局变量肯定拿不到正确结果——因为请求还没返回呢。不用async:false是绝对正确的选择,它会阻塞浏览器让页面卡住,用户体验极差。下面给你几种靠谱的解决方案:
方法1:把依赖全局变量的逻辑放在success回调里
这是最直接的方式。既然异步请求完成后才会进入success函数,那所有需要用到请求结果(也就是你要赋值的全局变量)的代码,都放在这个回调里就行。
修改你的代码示例:
// 先声明全局变量 let globalMsg; function callPublish(authorId){ var _shareDetail = artEditor.getContent(); document.getElementById("shareAuthorIdInput").value = authorId; document.getElementById("shareDetailInput").value = _shareDetail; var detailData = { data:JSON.stringify({ "shareTitle":$("#shareTitleInput").val(), "shareAuthorId":$("#shareAuthorIdInput").val(), "shareDetail":$("#shareDetailInput").val() }) }; $.ajax({ url:"/pubShare", type: 'POST', data: detailData, success: function (msg) { // 这里给全局变量赋值 globalMsg = msg; // 所有需要用globalMsg的逻辑都放在这里 alert(globalMsg); doSomethingWithGlobalMsg(); // 比如调用其他依赖这个变量的函数 } }) } function doSomethingWithGlobalMsg() { // 这里可以安全使用globalMsg console.log('全局变量的值:', globalMsg); }
方法2:用Promise封装Ajax,配合async/await
如果你的环境支持ES6+(现在大部分浏览器都支持),用Promise和async/await可以让异步代码看起来像同步的,可读性大大提升。
jQuery的Ajax本身就返回一个兼容Promise的Deferred对象,所以可以直接这样写:
let globalMsg; async function callPublish(authorId){ var _shareDetail = artEditor.getContent(); document.getElementById("shareAuthorIdInput").value = authorId; document.getElementById("shareDetailInput").value = _shareDetail; var detailData = { data:JSON.stringify({ "shareTitle":$("#shareTitleInput").val(), "shareAuthorId":$("#shareAuthorIdInput").val(), "shareDetail":$("#shareDetailInput").val() }) }; try { // 用await等待请求完成 const msg = await $.ajax({ url:"/pubShare", type: 'POST', data: detailData }); // 赋值全局变量 globalMsg = msg; // 后续逻辑可以直接用globalMsg alert(globalMsg); doSomethingWithGlobalMsg(); } catch (error) { // 处理请求失败的情况 console.error('请求出错:', error); } }
注意:await必须放在async标记的函数里,所以callPublish要加上async关键字。
方法3:使用自定义回调函数传递结果
如果不想把所有逻辑都塞在success里,可以定义一个回调函数,把请求结果传进去,在回调里处理赋值和后续操作:
let globalMsg; function callPublish(authorId, callback){ var _shareDetail = artEditor.getContent(); document.getElementById("shareAuthorIdInput").value = authorId; document.getElementById("shareDetailInput").value = _shareDetail; var detailData = { data:JSON.stringify({ "shareTitle":$("#shareTitleInput").val(), "shareAuthorId":$("#shareAuthorIdInput").val(), "shareDetail":$("#shareDetailInput").val() }) }; $.ajax({ url:"/pubShare", type: 'POST', data: detailData, success: function (msg) { // 调用回调函数,把结果传过去 callback(msg); }, error: function(error) { callback(null, error); // 失败也通知回调 } }) } // 调用callPublish的时候传入回调 callPublish(123, function(msg, error) { if (error) { console.error('请求失败:', error); return; } // 赋值全局变量 globalMsg = msg; alert(globalMsg); doSomethingWithGlobalMsg(); });
补充:为什么不能直接在Ajax外面赋值?
举个简单的执行顺序例子你就懂了:
- 调用
callPublish - 发送Ajax请求(但浏览器不会等结果,直接走下一步)
- 执行Ajax代码块后面的逻辑(如果有的话)
- 一段时间后请求返回,才进入
success函数
所以如果在Ajax外面写globalMsg = msg,此时msg还没被赋值,拿到的只会是undefined。
总结一下,核心就是不要和异步操作抢顺序,所有依赖异步结果的逻辑都要放在请求完成后的回调、Promise的then或者async/await的后续代码里。
内容的提问来源于stack exchange,提问作者Chris.Jiang
相关产品推荐
相关产品推荐

