如何将Ajax.responseText赋值给变量?异步请求赋值问题求助
解决异步AJAX请求中无法正确获取返回值的问题
哥们,我太懂你这种困惑了——异步代码的执行逻辑总是跟咱们的直觉对着干,你现在遇到的问题核心就是:你的ajax.touch函数在AJAX请求还没完成的时候就已经执行完毕并返回了undefined,而onreadystatechange里的返回值根本没地方去。既然同步模式已经被弃用,咱直接上几种现代异步处理方案:
先搞懂问题出在哪
你当前的代码里,ajax.send()之后,ajax.touch函数就直接结束了,没有返回任何值(所以a是undefined)。而onreadystatechange是一个异步回调,只有当AJAX请求完成、服务器返回数据后才会触发,这时候函数早就执行完了,里面的return response根本不会影响到外面的a。
方案1:使用回调函数(最基础的异步处理方式)
修改ajax.touch,让它接受一个回调函数参数,当请求成功时把结果传给这个回调:
var ajax = { touch: function(url, callback) { var ajax = new XMLHttpRequest(); ajax.open('GET', url); ajax.send(); ajax.onreadystatechange = function(){ if(this.readyState == 4 && this.status == 200) { var response = this.responseText.toString(); callback(response); // 请求成功时调用回调传递结果 } }; }, } // 调用方式 ajax.touch('session.php', function(result) { var a = result; console.log(a); // 这里会正确输出"ok" });
方案2:用Promise封装(更灵活的异步管理)
Promise是ES6引入的异步处理标准,能让异步代码的逻辑更清晰,还能避免回调地狱:
var ajax = { touch: function(url) { // 返回一个Promise对象 return new Promise(function(resolve, reject) { var ajax = new XMLHttpRequest(); ajax.open('GET', url); ajax.send(); ajax.onreadystatechange = function(){ if(this.readyState == 4) { if(this.status == 200) { var response = this.responseText.toString(); resolve(response); // 请求成功时,把结果传给resolve } else { reject(new Error('请求失败,状态码:' + this.status)); // 请求失败时,把错误传给reject } } }; // 处理网络错误 ajax.onerror = function() { reject(new Error('网络请求出错')); }; }); }, } // 用.then()链式调用处理结果 ajax.touch('session.php') .then(function(result) { var a = result; console.log(a); // 输出"ok" }) .catch(function(error) { console.error(error); // 捕获并处理错误 });
方案3:async/await(最简洁的写法,基于Promise)
如果你的运行环境支持ES2017+(现代浏览器、Node.js 8+),可以用async和await让异步代码看起来像同步代码一样直观:
var ajax = { touch: function(url) { return new Promise(function(resolve, reject) { var ajax = new XMLHttpRequest(); ajax.open('GET', url); ajax.send(); ajax.onreadystatechange = function(){ if(this.readyState == 4) { if(this.status == 200) { var response = this.responseText.toString(); resolve(response); } else { reject(new Error('请求失败,状态码:' + this.status)); } } }; ajax.onerror = function() { reject(new Error('网络请求出错')); }; }); }, } // 必须在async函数内部使用await async function getSessionResult() { try { var a = await ajax.touch('session.php'); // 等待Promise完成,直接拿到结果 console.log(a); // 输出"ok" } catch(error) { console.error(error); // 捕获错误 } } // 执行函数 getSessionResult();
这几种方案都遵循了异步编程的规范,不会像同步模式那样阻塞主线程,是现在前端处理异步请求的标准方式。
内容的提问来源于stack exchange,提问作者brunobliss
相关产品推荐
相关产品推荐

