V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
m939594960
V2EX  ›  问与答

JS 越跑越卡 一会儿就卡死了

  •  
  •   m939594960 · 2015-11-13 16:43:24 +08:00 · 3271 次点击
    这是一个创建于 3299 天前的主题,其中的信息可能已经有所发展或是发生改变。
    function  goto()
        {
            var _this=$('.urls span.url').eq(0);
            var b = new Base64();
            $('#cai_web').attr('src',"/cai_content/"+b.encode (_this.html())+'-'+_this.attr('data-gid')+'-'+'{{ $id }}');
            $('#cai_web').load(function()
            {
                _this.appendTo('.urls .item .ok');
                if (go==true){
                    goto();
                }
            });
        }
    

    做采集的时候 需要用到的 JS 但是发现这个段 JS 越跑越卡 一会儿就卡死了
    哪个地方有问题? 该如何解决呢?

    28 条回复    2015-11-13 22:36:59 +08:00
    penjianfeng
        1
    penjianfeng  
       2015-11-13 16:57:51 +08:00
    你的变量 go 呢?一直 true ?
    m939594960
        2
    m939594960  
    OP
       2015-11-13 17:02:58 +08:00
    @penjianfeng
    就是跑一条 扔一条 然后继续跑 让他一直跑下去
    go 这个变量 当点击停止按钮之后就会变成 false
    CodingPuppy
        3
    CodingPuppy  
       2015-11-13 17:14:59 +08:00
    哪里跑一条仍一条了?都在内存里
    m939594960
        4
    m939594960  
    OP
       2015-11-13 17:18:09 +08:00
    @CodingPuppy
    比如 一共 100 条 url 放到一个 div 里
    取一个 url 然后 iframe 传 encode 的 url 到后台
    然后等待 iframe 加载完成 吧这个 url 传到另一个容器里
    继续执行相同的动作

    现在问题就是跑到第 19~20 条 浏览器就崩溃了
    jasontse
        5
    jasontse  
       2015-11-13 17:18:11 +08:00 via iPad
    @m939594960
    上一个 goto 没结束就套下一个 goto ,哪里跑一条扔一条了。
    lucky2touch
        6
    lucky2touch  
       2015-11-13 17:19:43 +08:00
    手机上回了两次没成功,上面说得很清楚了,没有释放......
    m939594960
        7
    m939594960  
    OP
       2015-11-13 17:21:48 +08:00
    @jasontse goto 后面没有代码了 应该算结束了吧 要 retrun ''去结束么?
    @lucky2touch 怎么释放呢? 谢谢!
    learnshare
        8
    learnshare  
       2015-11-13 17:32:56 +08:00
    递归地在跑吧,没有释放什么东西
    kokdemo
        9
    kokdemo  
       2015-11-13 17:41:05 +08:00
    ……这么简单的效果用 settimeout 会不会好一点?
    m939594960
        10
    m939594960  
    OP
       2015-11-13 17:45:30 +08:00
    @learnshare 这种情况不能用递归么。 应该去用 while ??
    @kokdemo 得网站加载完毕后 在加载另一个 iframe 啊
    m939594960
        11
    m939594960  
    OP
       2015-11-13 17:45:45 +08:00
    @kokdemo 得一个 iframe 加载完毕后 在加载另一个 iframe 啊
    kokdemo
        12
    kokdemo  
       2015-11-13 17:47:27 +08:00
    @m939594960 可以循环的检测 iframe 的状态
    检测加载完成,就触发下一个 iframe
    m939594960
        13
    m939594960  
    OP
       2015-11-13 17:48:28 +08:00
    @kokdemo 嗯我尝试一下 应该是可以得 但是总想找个完美的方法
    sunjourney
        14
    sunjourney  
       2015-11-13 17:50:07 +08:00
    这是学过递归还是没学过呢,出口在哪里?用循环加 flag 控制,另外你的 Indentation 是什么教派的?
    otakustay
        15
    otakustay  
       2015-11-13 18:06:41 +08:00
    楼主的各位,这货似乎不是个递归,有个异步+callback 在里面……
    m939594960
        16
    m939594960  
    OP
       2015-11-13 18:08:28 +08:00
    @sunjourney 缩进 是在复制的时候出了一些小问题 现在找到几种方法了 while 或者 settimeout 但是我还是不懂为什么我这么写不行 。。 求教谢谢
    bdbai
        17
    bdbai  
       2015-11-13 18:17:08 +08:00 via iPhone
    每次回调都会保留作用域 开调试器检查一下
    LancerComet
        18
    LancerComet  
       2015-11-13 18:26:18 +08:00
    go == true ? setTimeout(goto, 1) : void(0);

    楼主试试:
    ```
    var i = 0;
    function a (param) {
    param = param || 0;
    console.log("a" + param);
    if (i < 3) {
    a(1);
    i++;
    }
    console.log("a() executing finished.");
    }
    ```

    ```
    var i = 0;
    function a (param) {
    param = param || 0;
    console.log("a" + param);
    if (i < 3) {
    setTimeout(a.bind(0, i), 1);
    i++;
    }
    console.log("a() executing finished.");
    }
    ```
    LancerComet
        19
    LancerComet  
       2015-11-13 18:33:50 +08:00
    @m939594960
    楼主这么写的行为: goto 还没有退出就在 goto 内再次执行 goto
    加了 setTimeout 后的行为:向任务队列登记一个新的计时器任务后退出 goto.
    HunterPan
        20
    HunterPan  
       2015-11-13 19:14:58 +08:00
    你这个用法会不会造成栈溢出啊 有点递归( js 不大懂)
    HunterPan
        21
    HunterPan  
       2015-11-13 19:16:06 +08:00
    @otakustay 要看的 callback 怎么处理的才能决定是否递归吧
    aivier
        22
    aivier  
       2015-11-13 19:45:00 +08:00
    $(...).load() 不是用来加载数据的么,例如

    $("username").load("/getUserName.php")
    dphdjy
        23
    dphdjy  
       2015-11-13 19:55:22 +08:00
    iframe 有父对象~如果可以交互在子 document 建立玩在反馈~~感觉省好多事~~
    m939594960
        24
    m939594960  
    OP
       2015-11-13 20:15:33 +08:00
    @kokdemo
    @sunjourney
    @ 、 bdbai
    @LancerComet
    @HunterPan
    @dphdjy
    找到问题了。 其实并不是递归的问题。 是个非常蛋疼的问题 。。
    我每次循环的时候都给 iframe 加上了一个监视 load 的事件
    然后 goto 就无限的运行了。。 现在在前面加个$('#cai_web').unbind('load'); 然后再进行监视就 ihaole
    aivier
        25
    aivier  
       2015-11-13 20:18:06 +08:00
    孤陋寡闻了...从未在循环里设定过事件绑定,用手机写的代码测试出来了刚想回复发现正好你也发现问题了...
    m939594960
        26
    m939594960  
    OP
       2015-11-13 20:18:40 +08:00
    @LancerComet 嗯 谢谢你 以后不用递归了 用这种 settimeout 应该效果更好
    @aivier 我查了一下
    http://www.w3school.com.cn/jquery/ajax_load.asp
    http://www.w3school.com.cn/jquery/event_load.asp
    应该是一个方法两个用途
    @dphdjy 嗯这样也不错
    otakustay
        27
    otakustay  
       2015-11-13 21:57:44 +08:00
    @HunterPan 那个是 jQuery 的 load 嘛,是个异步的,不会记在同一个 call stack 上面的,除非楼主坑我们$不是 jQuery
    aivier
        28
    aivier  
       2015-11-13 22:36:59 +08:00
    看了下官方文档,自动判断传入参数的,我感觉还是现在这种方式更好一些,如果准备一个一个来的话,这种 callback 方式就相当于多线程的了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   6035 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 39ms · UTC 02:12 · PVG 10:12 · LAX 18:12 · JFK 21:12
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.