1
iamcho 2015-11-10 14:50:17 +08:00
.done()
|
2
phithon 2015-11-10 14:51:52 +08:00
学 javascript ,心里必须有“回调函数”的概念。
比如你进行的 ajax 操作,需要等待服务端返回包再处理数据。 那你应该把处理数据的代码放在 ajax 的回调函数里,而不是像其他同步语言一样写在 ajax 代码后一行。 |
4
leavic OP @phithon 我写的是 grease monkey 脚本,和网站服务器是独立的两个部分,网站的 ajax 操作,怎么能设置我的函数作为回调呢?
BTW ,抛开回调的概念,难道就没有这种方法吗?因为交出 cpu 控制权做一个简单的 sleep ,这几乎在所有语言里都有,就算在 C 里也很容易实现。 |
6
ericls 2015-11-10 15:02:16 +08:00
js 是 non-blocking 是单线程的,如果你 sleep 了 那全部都会 block 住。。。
|
7
coolicer 2015-11-10 15:03:49 +08:00
@leavic 浏览器如果有这个 sleep 应该会把界面卡住吧,所以没发现可以这样。可以用一下 es6 的生成器,可以暂停 /重新 执行函数。
|
8
ChefIsAwesome 2015-11-10 15:12:03 +08:00
你光用 setTimeOut 怎么可能让浏览器假死
|
9
frozen2013 2015-11-10 15:13:33 +08:00
之前某墙攻击 github 的方法也是 setTimeout 来实现的,从没有人说那段循环加载导致引用那段 js 的网页死掉啊。 http://drops.wooyun.org/papers/5398
恐怕你在 setTimeout 引的 function 里做了太多耗时的计算工作了,你可以用 settimeout 来循环检查是某资源否加载完毕,确定加载完毕后再去做其他耗时的计算工作。 |
10
hronro 2015-11-10 15:16:25 +08:00
xmhttp.onreadystatechange = function(){
} |
11
hronro 2015-11-10 15:19:01 +08:00 1
我字还没打完怎么就发出去了
XMLHttp.onreadystatechange = function(){ if(XMLHttp.readyState==4 && XMLHttp.status==200){ //这里填完成数据加载后执行的内容 } }; |
12
Cloudee 2015-11-10 15:20:45 +08:00
你是不是在 while 里面 setTimeout 了……你在函数的最后 setTimeout 这个函数自己。
或者不用 while 循环用 setInterval |
13
hronro 2015-11-10 15:21:31 +08:00
js 是单线程,但是可以是异步的。像 AJAX 就是典型的异步执行
|
14
leavic OP @ChefIsAwesome
while(True) { if(check_something()==False) { setTimeOut(nop_function,100) } } 执行到这段明显卡住了,我希望的是 check_something 为 false 之后就 sleep 100 毫秒,这样占用的 CPU 时间顶多是有限次的 check_something()函数的执行时间,但实际看来并不是这样。 |
15
leavic OP @frozen2013 我就是做了个很简单的 a=2,if(a==1) alert('something'),基本上只有一个赋值和一个判断命令会被使用,我就把这段话当 nop 用了。
|
17
breeswish 2015-11-10 15:25:47 +08:00
alert 会阻塞
|
18
leavic OP @Cloudee 是的,我不是很清楚 setTimeOut 的工作方式,我以为这个函数可以实现非 block 的 sleep
|
19
Cloudee 2015-11-10 15:29:14 +08:00 1
@leavic 不是这样, setTimeout 是立即返回,并且在调度队列里面加上一个 n 毫秒后的任务,所以相当于你这个在不停地执行,并且不停地往调度队列里面添加新的任务。你的这个需求可以考虑用 setInterval ,并在函数体里面判断条件是不是满足,不满足就直接返回,满足再执行里面的逻辑。
|
20
leavic OP @Cloudee 对,我刚刚想明白这点,这样可以解释为什么 while 会卡死了, setTimeOut 对 CPU 来说和其他语句是一样的。我确实该试试 setInterval ,谢谢!
|
22
nisnaker 2015-11-10 15:35:54 +08:00
var t;
t = setInterval(function(){ if(check_something() == true) { clearInterval(t); // your funcs } }, 1000); 大概这样。 |
23
GtDzx 2015-11-10 15:38:15 +08:00
@leavic 建议你花个一天时间读读《 JavaScript The Definitive Guide 》,尤其是第 17 章 Handling Events 。浏览器端 JS 的事件驱动编程模型和一般的 C 语言程序有很大不同,我自己一开始也似懂非懂一知半解。与其针对一个具体例子分析来分析去,不如踏踏实实从头学习来的快。
|
24
frozen2013 2015-11-10 15:43:39 +08:00
额,你感到浏览器假死是因为 while ( true )生成了 n 多个 setTimeout,这个锅不能 setTimeout 来背.
用 settimeout 做定时器要这么写 function fn() { if (check_something()===false) { timer = setTimeout(fn, 100); } else { //TODO } } var timer = setTimeout(fn, 100); |
25
leavic OP @GtDzx 谢谢建议。
其实我自己用 C 写过简单的 RTOS ,所以调度系统对我来说是没什么难度的,用 RTOS 的思想做支撑,这些东西其实很容易理解,有点像练武的人打通任督二脉:) 我今天这个问题主要是没先检查 setTimeOut 函数是不是阻塞的,现在已经搞定了。 |
26
leavic OP @frozen2013 对的,我改用 setInterval 就好了。
|
27
Biwood 2015-11-10 16:00:23 +08:00
用 while 循环不就阻塞了整个 JavaScript 线程么,本来就是单线程,你这么一搞别的 js 代码都无法执行了。用定时器也不是什么好办法,频率高的话一样很影响性能。应该会有一些比较 hack 的方法可以解决你的问题,但是我觉得这种操作太敏感了吧,直接捕捉别人网站的数据?
|
28
pagxir 2015-11-10 16:07:57 +08:00 via Android
很明显,以楼主目前的水平,很难跟他解释清楚。
|
31
xiumushenzuo 2015-11-10 17:20:21 +08:00
建议题主还是看一下 23 楼推荐的内容,这和 RTOS 并不同,并不是多线程多任务的问题。
你现在的方式的确可以达到效果,但消耗了很多浏览器资源,而且不够优雅,并不是 js 这个语言通用的解决方案。 |
32
leavic OP @xiumushenzuo 谢谢,我会去看的。
|
33
FrankFang128 2015-11-10 18:55:38 +08:00
永远不要在 JS 实现 Sleep
|
34
maplerecall 2015-11-10 21:06:23 +08:00
在 js 中用循环和模拟 sleep 的方式判断是否加载完成是十分不对的, js 由于其特性与使用场景所需要的编程思想与 c 等非脚本语言是不太一样的。
lz 题目中描述的需求实际上是不需要任何 setTimeout 和 setInvertal 的,所要做的只是让这些 ajax 请求加载完成后来主动执行需要的操作。 23 楼的内容应该会有不少帮助~ |
35
maplerecall 2015-11-10 21:17:57 +08:00
@maplerecall 啊抱歉没看清楚前提_(:3 」∠)_
如果是 grease monkey 这种插入式脚本可以通过监听 DOMNodeInserted 事件来判断是否已处理完请求到数据 不过我记得这个似乎可以在页面加载前就执行?也许可以直接复写浏览器的 XMLHttpRequest 来直接获取请求数据 XD |
36
leavic OP @maplerecall 但这还有个问题,例如京东页面上的无货提示,就是 js 加载出来的,但并不是一定会有无货提示出现(碰上全有货的话),这种情况下,是不是 DOMNodeInserted 事件就不一定发生了。
|
37
zhuangzhuang1988 2015-11-10 21:41:39 +08:00
用下老赵的 winjs
|
38
dqh3000 2015-11-10 22:09:06 +08:00
|
39
SuperMonster009 2019-04-19 08:14:11 +08:00 via Android
mdn 提到可以用 promise
|