搜索

首页  >  问答  >  正文

javascript - js有没有可以检测一个同步方法执行时间的?

具体是这样,有没有一个可以检测同步方法执行时间的,就是如果这个执行时间过长,我就主动去kill掉这个方法

迷茫迷茫2753 天前908

全部回复(5)我来回复

  • typecho

    typecho2017-06-15 09:25:26

    这就要看你的同步方法是什么了?

    • 如果是第三方库提供的方法,那要看它本身有没有提供停止方法,若没有你也没有办法;

    • 如果是涉及到文件 i/o/delete/create 你可能就阻止不了,但你可以在它报错后写个逆函数执行来恢复原状;

    • 如果这个方法是你自己写的,并且有多个子函数,那么你可以在函数内部定义一个计时器,执行每个子函数前检查时间是否超过允许,这是一个变通的方法;

    • 如果这个方法是你自己写的,且只有一步,既然是个耗时方法,那估计有循环存在吧,那每次循环检查时间是可以的吧。。。

    回复
    0
  • 世界只因有你

    世界只因有你2017-06-15 09:25:26

    从 JS 的角度看,执行同步方法时,整个应用会阻塞在其中,这时即便是 setTimeout 异步触发的回调,也要在同步方法执行完成后的 Event Loop 中才能执行,因此不能够在同步方法中检查自身的执行时间并 Kill 自身。

    从计算机科学的角度看,题主的问题其实就是经典的停机问题:

    停机问题(英语:halting problem)是逻辑数学中可计算性理论的一个问题。通俗地说,停机问题就是判断任意一个程序是否能在有限的时间之内结束运行的问题。该问题等价于如下的判定问题:是否存在一个程序P,对于任意输入的程序w,能够判断w会在有限时间内结束或者死循环。

    这个问题是 NP 难的,这也就意味着不存在时间复杂度上可接受的算法来直接解决。

    但跳出学院派的算法来看,工程中的变通方式很多,如采用 Web Worker 或 PM2 的进程管理机制等,这里不再展开了。

    回复
    0
  • 怪我咯

    怪我咯2017-06-15 09:25:26

    那你只能搞多线程了……
    http://www.w3school.com.cn/ht...
    然而、js如何kill掉另个方法也是个迷……
    说到底……你直接用异步不就好了||||

    回复
    0
  • 黄舟

    黄舟2017-06-15 09:25:26

    console.time("time1")
    $("*").each(function(){})
    
    console.timeEnd("time1") 

    经提醒,这样确实不是办法,另一个低端的办法恐怕只能这样了:

        var func = function(t1) {
            var sum = 0,
                t2;
            for (var i = 0; i <= 10000; i++) {
                sum += i;
                t2 = new Date().getTime() - t1;
                if (t2 > 1) {
                    throw '超时';
                }
            }
            console.log(sum);
        };
    
        try {
            func(new Date().getTime());
        } catch (e) {
            console.log(e);
        }

    不一定适合所有业务,而且打点本身会让程序变得更慢。

    回复
    0
  • 女神的闺蜜爱上我

    女神的闺蜜爱上我2017-06-15 09:25:26

    Webworker可以在另一个线程中执行你的计算逻辑,onmessage方法可以接受执行的结果,terminate
    方法可以终止webworker的执行

    var job001DoneIndictor=false;
    var myWorker = new Worker('job001.js');
    //接收worker传递过来的数据
    myWorker.onmessage = function(event){
        
      job001DoneIndictor=true;
    };
    setTimeout(function(){
        if(!job001DoneIndictor){
           myWorker.terminate();
           myWorker =null;
        }
    },5000);//设置超时检测时间

    回复
    0
  • 取消回复