大概就是这样一个情况。
需要从后台读取一些id,可能上百个。
$.ajax({
url: 'data.json',
type: 'post',
dataType: 'json',
success:function(data){
var _code = data.code; //ajax外无法访问_code
window._code = data.code; //ajax外无法访问_code
},
})
比如data.code就是一个length可能上千的一个数组。
那么我应该,如何对他进行一个保存?
我发现在ajax里边存储的数据,在其他地方都无法访问额?
请问遇到这种情况,应该怎么办?
window._code = data.code;
这个写法,要等ajax 请求完成了之后才能在外部访问的 ;
你之所以觉得在外部访问不了是因为你访问这个数据的时候 因为函数的异步问题,他都还没获取到这个数据呢 ,所以你可以在success
函数里面调用一个函数,然后去实现你想要的功能
涉及到ajax异步操作的变量赋值,最好是引入jquery的 deferred 对象,可以避免变量获取不到值的情况。
另外,jquery的ajax回调还是建议使用promise的形式
ajax请求(async:false|true)加载同步与异步的功能区别
1、异步情况:ajax单独开启一个请求,ajax请求未完成即window._code未被赋值时,外部先调用window._code,因为值为空undefined;
2、同步情况:ajax请求完成后(success或error等),window._code被赋值,后续外部操作才可以调用。
示例http://codepen.io/AnnatarHe/pen/RWMLam
在外面定义
var data;
$.ajax({
url: 'data.json',
type: 'post',
dataType: 'json',
async:false,
success(data){
var _code = data.code; //ajax外无法访问_code
data = data.code; //ajax外无法访问_code
},
})
console.log(data);
只是一个异步问题。想要在外部实时访问到_code其实很简单,对于ie8以下的浏览器。唯一的方法就是定时器轮询,因为你无法知道在js的单一线程中什么时候回调你的success。而对于ie8以上的浏览器已经兼容es5了,事情太好办了,无非是在你的windo._code设置setter罢了。。。所以此时你需要一个浏览器嗅探,低版本需要setInterval,而现代浏览器只需setter。例如
var myObj = {a: null};
Object.defineProperty(myObj, "_code", {
get : function () {
return this.a;
},
set : function (val) {
//your code...
//...
//set value...
this.a= val;
}
});
而楼上的各种答法其实脱离不开的就是ajax编程中的金字塔式编程。在promise规范出来之后,此类编写代码方式是不怎么优雅的。所以基于优雅回调且基于$。我们可以写成
$
.ajax({
url: 'data.json',
type: 'post',
dataType: 'json',
async:false})
.done(function(res) {
//you code...
});
var一个全局变量,然后回调里面存储不就行了
var proList = null;
var index = {
getProList : function(){
var self=this,
url=$('#J_ProList').val();
$.ajax({
type:'GET',
url:url,
dataType:'jsonp',
jsonpCallback:'jsonp0',
success:function(resp){
proList=resp;
self.viewProList(proList);
},
error:function(){
}
});
},
viewProlist : function(prolist){
//处理部分
}
}
一句话改成同步的模式就可以
不是不可以访问, 而不是你访问的时机不对,
使用 window._code = data.code;
这种形式即可, 或者 _code = data.code
也可以.
但你访问的时候, 需要确定,你的 ajax
已经执行完成了.
以你目前的代码来看, 这个请求是异步的, 所以你在发出请求之后就去访问是得不到的, 只有确保ajax在完成之后,再去访问就可以了.
正确的做法是在你在的 success
函数中 去触发你要访问这个数据的代码.
类似于:
$.ajax({
url: 'data.json',
type: 'post',
dataType: 'json',
success:function(data){
window._code = data.code; //ajax外无法访问_code
ok_go();
//下面是通过参数传递的方式
//ok_go(data.code);
}
});
function ok_go(data){
console.log(window._code);
//或者也可以通过参数传递过来
//console.log(data);
}
当然还一种比较笨的方法:
//ajax 的 success 中使用 window._code = data.code 来保存数据
//延时100毫秒去检测
setTimeout(function(){
if(typeof window._code !== 'undefined'){
//Ajax完成了, 数据也已经得到了
console.log(window._code);
return;
}
//还没有请求完成, 再过100毫秒再去检测一次.
setTimeout(arguments.callee, 100);
}, 100);
看楼上的这些答案,有些是答主根本就不知道原因在那乱说,有些是说的比较片面。
那我来解释下吧。
首先答主你要了解,js
是单线程的,就是他从被调用开始,会一条道跑到黑,直到结束为止。
然后$.ajax()
当然,这是个封装过的函数。无论是通过ActiveXObject
或者XMLHttpRequest
的这种真·ajax
方式,还是jsonp
这种伪·ajax
的方式,它们都是异步的,而且是需要等待相应的。
那么,我帮你捋一下思路,当页面加载了脚本之后就会开始运行,一直运行到最后的一句为止。当然,其中也许会有你的这句$.ajax
,但是也只是发起一个请求就没了,(只不过js引擎在背地里会提供一个回调的入口,这个入口暂且放一边,后面会说)然后丝毫不会等待的继续运行下面的语句,直到最后。
既然是ajax
请求,就会有响应的时候。请求相应就会调用之前提到的回调入口,而你需要做的就是,把你想要执行的代码注册到这个回调入口里($.ajax
里的success
再或者error
以及complete
都是回调的入口)
也许光说理论你有点懵。那我给你写个例子吧:
首先声明一个函数:
var show = function() {console.log(window.data);};
然后来这么两句:
$.ajax({url: 'xxx', success: function(data) {window.data = data;show();}});
show();
(故意将ajax
这行写成一句,方便看到我的重点)
假设可以通过xxx
接口成功返回字符串:"abc"
,那么你会看到控制台里:
undefined
"abc"
第一个undefined
是$.ajax
后面的show();
打印出来的;
第二个"abc"
是$.ajax
中注册的success
回调中打印出来的。
这里有两个重点:
先执行的是
$.ajax
后面的show();
,而不是$.ajax
中的success
。原因:因为是异步,因为是单线程因为第1点,先执行
show();
的时候,ajax
的请求还没有返回,所以window.data
还没有被赋值,所以就是undefined
以上
跟楼上一样 把你要的处理流程另外定义成函数 然后在success后调用这个方法 带上你的数据即可
主要就是在外面定义和window._code = data.code;
这种方法都是可行的,你访问不到是因为ajax还没请求完成,你可以在success中添加回调来处理
$.ajax({
url: 'data.json',
type: 'post',
dataType: 'json',
success(data){
var _code = data.code; //ajax外无法访问_code
data = data.code; //ajax外无法访问_code
handleData(data);
},
})