jQuery $.when调用$.ajax无法获取responseJSON数据问题
问题根源
你打印出readyState: 1的对象是$.ajax返回的jqXHR请求对象,出现这个问题的核心原因有两个:
$.ajax是异步请求,调用ajaxcall()时请求刚建立还没完成,不会阻塞后续代码执行,此时直接读取返回值只能拿到未完成的请求对象,根本拿不到响应数据- 你写在
success回调里的return data不会作为ajaxcall()的返回值,回调函数的返回值只会被jQuery内部接收,不会透传到外层函数调用处。
请求状态readyState: 1对应「请求已建立、尚未发送完成」的阶段,这个阶段jqXHR对象上还没有responseJSON属性,自然无法访问实际响应内容。
正确写法
1. 调整封装的ajax函数
不要在封装内部写success/error回调处理业务逻辑,直接返回jqXHR对象即可,把数据处理的控制权交给调用方:
function ajaxcall(){ return $.ajax({ url: "url", type: "POST", data: form_data, dataType: 'json', contentType: false, cache: false, processData:false }); }
2. 基础调用方式(单请求)
通过jqXHR自带的.then()/.done()方法,在请求完成的回调里拿到响应数据,所有依赖响应数据的逻辑都必须写在回调内部:
jQuery(document).ready(function() { ajaxcall() .done(function(response) { // 这里拿到的就是接口返回的真实响应数据 console.log(response); if(response == 'invalid'){ alert("invalid data"); } // 后续所有依赖response的逻辑都写在这里 }) .fail(function(err) { // 请求异常的处理逻辑 console.log('请求出错', err); }); });
3. 结合$.when的调用方式(适合多请求并行场景)
如果需要等一个或多个ajax请求全部完成后再处理数据,就用$.when接收返回的jqXHR对象:
jQuery(document).ready(function() { // 单请求场景 $.when(ajaxcall()).done(function(response) { console.log('请求完成拿到数据', response); }); // 多请求并行场景,等所有请求都完成才执行回调 // $.when(ajaxcall(), otherAjaxCall()).done(function(res1, res2) { // // res1是第一个请求的响应,res2是第二个请求的响应 // console.log(res1, res2); // }); });
注意事项
不要尝试把异步请求的响应赋值给外部全局变量、再在回调外部读取使用。只要代码写在请求回调的外面,执行时机永远早于请求完成的时机,要么读到未完成的jqXHR对象,要么读到
undefined。如果一定要在回调外部拿到数据后再执行后续逻辑,必须把后续逻辑放到回调函数内,或者使用async/await语法(注意jQuery 3.x以上版本才支持jqXHR和async/await适配)。
内容的提问来源于stack exchange,提问作者Kevin Lindmark
相关产品推荐
相关产品推荐

