setinterval 和 setTimeout调用方式以及浏览器缓存问题 Myth丶恋晨 2022-05-20 05:16 184阅读 0赞 setinterval 和 setTimeout调用方式以及浏览器缓存问题 js中setinterval 和 setTimeout 可以做定时器,这个大家都知道, 关于这两个方法的区别,网上也有很多文章说的很清楚。 在此我还想说一说2个问题: 1,关于调用方式的书写。 比如: function showCallInAndOut()\{ //xxx \} //setTimeout("showCallInAndOut()",1000); //setTimeout(showCallInAndOut,1000); 上面的这两中调用方式都是对的!!! 如果第一个参数是字符串,那里面的方法名需要带括号; 如果第一个参数是变量,就直接写变量名(方法名),不能带括号。 下面是例子,包括传参的调用: <html> <head> <title> New Document </title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <script src="jquery-1.7.1.js" type="text/javascript"></script> </head> <body> <input type="text" value="" id="inter"/> </body> </html> <script> var aaa=1; function showCallInAndOut(){ $("#inter").val("showCallInAndOut调用"+aaa+"次"); aaa++; } var bbb=1; function sayHi(word){ $("#inter").val("sayHi调用"+bbb+"次,参数是:"+word); bbb++; } //setInterval("showCallInAndOut()",1000); //正确 //setInterval(showCallInAndOut,1000); //正确 //setTimeout("showCallInAndOut()",1000); //正确 //setTimeout(showCallInAndOut,1000); //正确 //传参的调用方式 var param="hi,gril!"; //setInterval("sayHi(param)",1000);//这个方式可以传参 //setInterval(sayHi,1000); //这个方式不能传参 //setTimeout("sayHi(param)",1000);//这个方式可以传参 //setTimeout(sayHi(param),1000);//这个方式不能传参 /* 传参的调用方式结果已经很明了了。 从结果我们可以猜想,如果传入字符串,那浏览器在底层可能调用了eval()方法。 如果传入变量,就直接调用这个变量,至于这个为什么不能传参,就不清楚了。 */ </script> 2,关于在ajax做定时器调用的问题(每个一段时间发请求)。 假如我们要刷新页面上某个值,并且需要不断地,时时的刷新,大家都会想到 利用js的定时器不断发ajax请求,在回调函数中巴页面上的值改变这个思路。 在实际项目中,我遇到一个问题: 我使用setInterval定时调用一个方法showCallInAndOut(), 这个方法就是一个ajax。奇怪的是有时候定时刷新很正常,这和我初始的思路一致, 有时候,定时刷新就没有效果,我在后台打上断点,输出打印都没反应。 开始我以为是setInterval出了问题,就在这个方法里加了一行计数: $("\#inter").val("showCallInAndOut调用"+aaa+"次"); aaa++; 记过页面上这个aaa是一直变化的,也就是说setInterval一直正常! 那问题只能是里面的方法showCallInAndOut()有问题! 这个方法就是ajax,没什么特别的,可就是不调用,我甚至在页面加个按钮 直接调用这个showCallInAndOut()也没反应。 后来,我在页面初始化的时候调一下showCallInAndOut()刷新页面某个值。 然后再调用setInterval,当然这个setInterval里面还是调用showCallInAndOut()。 接着我再测试的时候发现,页面初始化时会调用,但是setInterval里面的却不调用!当我改变 数据库中的值,再刷新页面,这两个都不调用! url绝对是正确的,为什么就不调用呢?由此我突然想到浏览器的缓存! 所以我在url后面加上一个随机参数。在页面初始化那个方法里不加随机参数, 在setInterval里面的方法加上随机参数。 结果: 2-1,初次进入那个页面: 页面初始化会调用,setInterval也调用。 2-2,我改变数据库的值,刷新那个页面时: 页面初始化会不调用,setInterval调用! 而且页面首先会显示前一次的数值!过了定时的那几秒后就会显示数据库实际的数值! 结果很明显,js方法肯定会调用,但是ajax请求不一定走! 为什么呢?浏览器缓存! 在ajax中请求的url在浏览器中是会留下缓存的!如果浏览器发现新的请求和以前的请求一模一样, 浏览器就直接把缓存中的结果拿出来了,这个请求就不走了。这不是什么新鲜的问题,我以前 也遇到过,就是在做图片上传的时候,第一次用户上传一张图片,在点击提交前又想改换另外一张图片(名字 是一样的),我在后台把图片名字改成用户的名字,这样图片的url总是一样的,即使真的上传了改变后的 图片,页面上还显示改变前的那一张!在url后面加上随机参数就没有问题了。归根到底,就是 浏览器缓存的问题。他认为你的请求或者url是和前面一样的,他就直接拿结果!ajax也一样! 就像我这一次做的2-2,之所以先显示以前的值(数据库已经变值了),页面还能显示出来,后后面 setInterval请求中我都加了随机参数,结果就显示正确的,后台代码也能走,这就是很清楚了。 页面初始化的那个url已经在浏览器有了缓存,你刷新页面,走这个方法时,ajax就没走,直接从缓存中取; 后面的setInterval请求url因为有了随机参数使url每次都不一样,浏览器只能重新发送请求,这样取到的值 就是正确的,数据库实际的值。 至于为什么不加随机参数时有时候setInterval能正常走,有时候不能原因就是: 正常走的情况浏览器没有缓存,不正常的时候是有了缓存。 那什么情况下浏览器才会留下缓存呢?这个哥们就不清楚了。 页面的url和请求最好加上随机变量,这样就会很有效地避免一些“诡异”问题,算是培养 良好的编码习惯吧。 至于随机参数,在这里我也说一下吧。 其实很简单,在url后面加一个参数。 比如: "xxxxx/voice/getCallInInfo.action?ss=aaa"; 这个ss如果是随机的,就可以。 在js中,我比较喜欢这样: url: "<%=path%>/voice/getCallInInfo.action?ss="+Math.random() 在jsp中,就更好办了,利用日期,随机数等等生成一个无规律的字符串加在url后面就可以。
还没有评论,来说两句吧...