我们都知道jquery中的ajax或者getJSON调用默认是异步的,但是异步的话会有个问题,比如我们对外面的变量赋值会不成功,因为代码不管getJSON方法是否执行完,继续走到下面了,那么变量就不会赋值成功。如果我们期望执行完getJSON再执行下面的代码。那么就需要设置同步模式。方法很简单,在getJSON调用的前插入下面这一行即可:
$.ajaxSetup({async:false});
完整试验代码如下:
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>test</title> </head> <body> <script src="//libs.baidu.com/jquery/2.0.0/jquery.min.js"></script> <script type="text/javascript"> var s=0; var data = {tag: "aaa"}; $.ajaxSetup({async:false}); $.getJSON("urlxxx", data, function (backdata) { s=666; alert(s + " ---1---"); }); alert(s + " ---2---"); </script> </body> </html>
我们期望的是:
先显示666 ---1---,然后再显示666 ---2---
事实上是:
先显示0 ---2---,然后再显示666 ---1---
显然并没有同步,反复试验都是如此,以上代码已经把无关代码都拿掉剩下最精简后的测试代码了。百度上导出搜,确定操作是正确的,要同步就是加那一行。于是我想是不是在getJSON中这个局部变量生存周期只在自己这个内部啊,可是以前正常用过啊。以前常用的代码怎么就不行了?可以确定以前是可以正常同步执行的。难道是我引用的jQuery版本太旧?看了下是1.8版本并不旧,用2.0版本测试问题也是依旧。
最奇怪的是,这个代码本来是从另外一个站点迁移来的,在另外一个站点是正常的,在这个站点怎么就运行不正常了呢?本来准备将jQuery版本用到最新,后来发现这个正常的站点也是用的1.8版本。
于是有捣鼓很久。。。火狐谷歌各个浏览器反复试。。。two hours later 搞技术就是这么折腾
最终我突然意识到两个站点的差别,一个是https的一个是http,是不是这里的差异呢?因为这个导致浏览器的限制策略差别?
于是给站点安装个ssl证书,配置好https,果然好了!天啊,一个s浪费了那么久的时间!可是以前http站点是可以正常用的啊,翻遍网络也没说到jQuery在https下才能同步。难道的最近改的么?找了找好像是在2018年开始有这策略的,不确定,有待考证。
后来在网上看到这么一句“ajax本来的目的就是进行异步操作, 而且最新的jQuery版本甚至已经弃用了async参数.如果你只是想利用ajax做服务器的交互,不需要异步刷新效果,那可以用回调函数.”我将版本切换为1.2.3测试发现问题依旧,说明不是他说的那样。
至于回调解决倒是个方案,我试了下确实可行,也算是一种变通的解决办法,就是将要执行的各个动作封装成函数,然后按放到回调处理里按条件调用执行。这样就避开了同步还是异步的问题。