求解答一个前端问题

2023-04-29 15:09:36 +08:00
 fu4k

我在学习 chrome 插件开发的过程中遇到一个问题,代码如下:

(function(){
    var protocol = window.location.protocol;
    var host = window.location.host;
    var href = window.location.href;
    var source = document.getElementsByTagName('html')[0].innerHTML;
    var target_list = [];
    var js_result = [];
    var source_href = source.match(/href=['"].*?['"]/g);
    var source_src = source.match(/src=['"].*?['"]/g);
    var script_src = source.match(/<script [^><]*?src=['"].*?['"]/g);

        if(source_href){
            for(var i=0;i<source_href.length;i++){
                var u = deal_url(source_href[i].substring(6,source_href[i].length-1));
                if(u){
                    target_list.push(u);
                }
            }
        }

        if(source_src){
            //var js_result = [];
            for(var i=0;i<source_src.length;i++){
                var u = deal_url(source_src[i].substring(5,source_src[i].length-1));
                if(u){
                    target_list.push(u);
                    var xhr = new XMLHttpRequest();
                    xhr.open("GET", u, true);
                    xhr.send();
                    xhr.onreadystatechange = function() {
                        var src = this.responseText;
                        var script_url = src.match(/( https?|http|ftp|file):\/\/[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]/g);
                        if(script_url){
                            for(var t=0;t<script_url.length;t++){
                                var y = script_url[t];
                                if(y){
                                    js_result.push(y);
                                }
                            }
                        }
                }

                }
            }
        }
        console.log(js_result)
        console.log(target_list)

问题是: console 打印出来的 js_result 和 target_list 是不同形式的(就好像一个数组是空的,一个数组包含了值), 如图:

点开空的那个▶️, 就能看到结果,但是没有直接显示出来

1353 次点击
所在节点    问与答
16 条回复
RaDisH7
2023-04-29 15:20:58 +08:00
因为你的 xhr 请求是异步的,可以去了解一下 JavaScript 的异步、同步、promise 这些东西 https://zh.javascript.info/async
fu4k
2023-04-29 15:26:33 +08:00
@RaDisH7 谢谢大哥 悟了 我去试试
fu4k
2023-04-29 17:42:25 +08:00
感觉 promise 、await 、async 理解起来好难🤯
fu4k
2023-04-29 19:12:56 +08:00
有没有好心人能给出 code 示例🙏
turan12
2023-04-29 19:46:57 +08:00
xhr.open("GET", u, true) 改为 xhr.open("GET", u, false) ,就创建了一个同步请求
huijiewei
2023-04-29 19:52:38 +08:00
@fu4k 很好理解啊。异步就是数据只能在 callback 里面取到,promise 就是承诺给你数据,要在 then 里面处理,async/await 就是异步转为同步代码
fu4k
2023-04-29 20:25:49 +08:00
@turan12 同步请求会有很多异常阻塞 qwq..
fu4k
2023-04-29 21:05:12 +08:00
付费求大佬赐教😭
@RaDisH7 @huijiewei @turan12
Yukiteru
2023-04-29 21:15:06 +08:00
可以用 fetch 啊,然后 await
huijiewei
2023-04-29 21:15:52 +08:00
@fu4k 付什么费。js_result 只有在 xhr.onreadystatechange 的方法里面才是真正的数据
huijiewei
2023-04-29 21:16:41 +08:00
onreadystatechange 就是 xhr 的一个 callback 。
stefanieewu
2023-04-29 21:31:02 +08:00
如果你不想改现在代码结构的话,就在 xhr 的回调里面判断拿到了多少条请求结束的结果,然后判断长度是不是超过了 soucre_src 数组的长度,如果超过,说明所有发出的请求都结束了(不管成功失败)这时候打印

if (source_src) {
//var js_result = [];
let index = 0;
let callbackFun = () => {
console.log(js_result)
console.log(target_list)
}
// ...其他代码
xhr.onreadystatechange = () => {
// 最后新加
index++;
if (index >= source_src.length) {
// 执行所有请求结束的回调
// callback()
callbackFun()
}
}
}

当然是建议用 promise + promise.all 去写,或者用 fetch ;

如果有其他问题,可以加我 vx:bGlqaWF0dTE5OTg=
fu4k
2023-04-29 21:32:19 +08:00
@Yukiteru fetch 试了,会有同源问题
lneoi
2023-04-29 22:46:22 +08:00
没看太懂问题是什么。
console 打印对象时也是引用的,打印语句执行的时候对象是空的,所以预览信息里面就是空的。当点开后会去读取最新的内容,刚好你这变量异步请求后会更新值,所以点开后会后跟预览不一样的信息。
fingers
2023-04-30 10:14:29 +08:00
@lneoi 感谢回复 问题是想在预览的时候就打印出结果
12 楼老哥已经帮忙解决了问题,谢谢大家
7gugu
2023-04-30 18:17:47 +08:00
直接在对应的位置输入“debug”,直接打断点就能看到对应的变量值了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/936435

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX