记录一次重新学习SetInternal和SetTimeout
优采云 发布时间: 2020-08-26 12:04记录一次重新学习SetInternal和SetTimeout
背景:
做一个Chrome的TamperMoney脚本,采集超星慕课全部学校:://。
这是一个二级联动的,左侧是城市、右上是26个字母,右下是要采集的中学列表,想要一次性把全部数据采集下来,必须不断点击城市和字母进行切换,数据是通过ajax异步加载后渲染到页面的。
总的来说是希望后端抓取到中学的名称和ID,用$.ajax传到自己写的ashx的方式中,再存到数据库里。
坑一:首先碰到的问题就是这样采集的数据因为跨域问题,无法$.ajax到localhost:1066/r.ashx?method=a 中,解决方法是使用JSONP
$.ajax({
url: "http://localhost:1066/handle/r.ashx?method=updateChaoXingSchool",
type: "get",
dataType:"jsonp", //使用jsonp
jsonp:"jsonpCallback",
jsonpCallback:"success_jsonpCallback",
data: {schoolId:id,name:name,letter:lt},
success:function(result){
csl++;
},
error:function(data){
}
});
后端context.response.write也必须和jsonpCallback中拟定的方式名一致才行,里面的内容倒是无关紧要:
context.Response.Write("success_jsonpCallback({\"result\":true})");
思路一:使用$.each嵌套循环来做,但是$.each是异步的,而JSONP也是异步的且难以强制设定为同步,就算是可以同步,也会抵挡网页造成点击风波失效,这样切换城市和字母又未能实现了。
思路二:使用for循环+sitetimeout,因为for循环是同步方式,settimeout可以控制$.ajax的运行间隔。 用过才深刻理解了setTimeout是个异步方式,换用了各类形式设定setTimeout(如i*1000)效果也十分差,即使次序和内容采集到是对的,也会导致浏览器卡顿崩溃。
思路三:前面的尝试使我彻底舍弃了使用循环来实现,改变使用定时器SetInternal实现:定时监控整个网页的情况,来判断怎么执行采集。原理:
1、点击启动按键:获取城市对象集合、当前校区对象集合;设定初始值,如起始城市、字母、学校的 Inex值。
2、设定定时器A,每0.1秒采集当前页面的中学,当前校区Index自增
3、if(当前校区Index==当前页面总校区数)
then
清除定时器A,避免在切换字母的过程中继续采集
点击切换下一个字母
else
采集学校数据……
4、 设定定时器B
5、
if(当前字母Index==26)
then
清除定时器B,避免在切换城市的过程中继续采集
点击切换下一个城市
else
采集学校数据……
最终代码: