此 BUG 复现率百分之一百
代码如下:
for(var i=0;i<10;i++){
GM_xmlhttpRequest({
url: "http://www.qq.com/",
responseType: "document",
headers:{'overrideMimeType': 'text/html;charset=gb2312'},
onload:
function(res){
console.log(i)
},
});}
我在油猴中使用此代码,但是输出并不是理想情况:
按代码执行来说 应该进入 For 循环后 访问 qq,获取到 QQ 的源代码然后打印当前循环次数,然后自增 i,进入下一次循环
理想情况打印的内容应该为 0-1-2....-9
但事实却是只会输出 10 个 10. 如图: https://www.hualigs.cn/image/60c0b3a27dd2c.jpg
而我如果稍加修改 将输出语句写在 GM_xmlhttpRequest 外面,for 循环的里面,则没有问题,如图: https://www.hualigs.cn/image/60c0b4086faa3.jpg
所以我认为就是 GM_xmlhttprequest 的问题,但是我不清楚这是 bug 还是什么别的原因导致的,有大佬知道吗?
1
hgc81538 2021-06-09 20:44:23 +08:00 1
for(var i=0;i<10;i++){
(function(i){ GM_xmlhttpRequest({ url: "http://www.qq.com/", responseType: "document", headers:{'overrideMimeType': 'text/html;charset=gb2312'}, onload: function(res){ console.log(i) }, }); })(i); } |
2
wangsongyan 2021-06-09 20:44:45 +08:00 via iPhone
onload 是回调函数,异步执行
|
3
zhuzhuaini OP |
4
zhuzhuaini OP @hgc81538 虽然顺序是乱的,但是好像没什么问题 能不能讲解下 (function(i)和最后的(i); 是啥作用
|
5
aloxaf 2021-06-09 21:22:25 +08:00
|
6
zhuzhuaini OP @aloxaf 全英文。。。很不友好....
|
7
OHyn 2021-06-09 21:35:03 +08:00
onload 是回调函数,异步执行,当它执行的时候,for 循环已经结束,i 的值已经是 10.
你把 var 改成 let 可解决问题。 这俩东西的作用域有区别。 |
8
zhuzhuaini OP @OHyn 刚刚试了下 var 改 let 似乎会引起别的问题(不过 onload 倒是没问题了) 我目前用了 L1 的方法 暂时没发现什么 BUG
|
9
knives 2021-06-10 00:04:14 +08:00
异步转伪同步的话,上 Promise chain 吧,用 await 语法来实现会比较简洁。
|
10
Yvette 2021-06-10 04:49:18 +08:00
需要看中文直接搜闭包也可以
|
11
muzuiget 2021-06-10 08:21:53 +08:00
老生常谈,GM_xmlhttpRequest 是异步函数, 用 Promise 和 await 解决。
|
12
linyinma 2021-06-10 09:27:52 +08:00
一般浏览器 JS 执行引擎是单线程:“事件驱动”, 调用 GM_xmlhttpRequest 是将消息留到事件队列,因此这个 for 循环只是把事件丢到队列中,等待本事件完成退出以后,JS 引擎线程再从事件队列处理处理刚丢进去的 GM_xmlhttpRequest 事件;
|
13
no1xsyzy 2021-06-10 09:30:16 +08:00
其实你了解下 CPS[1] 也就清楚怎么写了,不过这是个比较抽象的概念,实际工程上也不一定非得理解 CPS
简单地说,你这样 for(...){xhr({..., onload:x=>...})} 会同时发起十个续延,它们会产生某种竞态导致结果顺序不一致。 JS 的 var 关键词会传递同一个 ref alias,换 let 就会产生十个不同的 trn alias 了。当然,JS 的 refcap 并没有那么精确。 [1]: Continuation-Passing Style |
14
Rhilip 2021-06-10 16:09:36 +08:00
这不是油猴的问题,是你对 js 异步不了解。
|