Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/479.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何实施";功能超时“;在Javascript中—不仅仅是';设置超时';_Javascript_Timeout - Fatal编程技术网

如何实施";功能超时“;在Javascript中—不仅仅是';设置超时';

如何实施";功能超时“;在Javascript中—不仅仅是';设置超时';,javascript,timeout,Javascript,Timeout,如何在Javascript中实现a,而不是窗口.timeout,而是类似于会话超时或套接字超时——基本上是一个“函数超时” 系统中允许经过的指定时间段 在指定事件发生之前,除非另有规定 事件先发生;在任何一种情况下,当 任何一个事件都会发生 具体来说,我需要一个javascript观察计时器,它将观察函数的执行时间,如果达到或超过指定时间,则观察计时器将停止/通知执行函数 非常感谢您的帮助!非常感谢。我不完全清楚你在问什么,但我认为Javascript没有按照你想要的方式工作,因此无法完成。例如

如何在Javascript中实现a,而不是
窗口.timeout
,而是类似于
会话超时
套接字超时
——基本上是一个“
函数超时

系统中允许经过的指定时间段 在指定事件发生之前,除非另有规定 事件先发生;在任何一种情况下,当 任何一个事件都会发生

具体来说,我需要一个javascript
观察计时器
,它将观察函数的执行时间,如果达到或超过指定时间,则观察计时器将停止/通知执行函数


非常感谢您的帮助!非常感谢。

我不完全清楚你在问什么,但我认为Javascript没有按照你想要的方式工作,因此无法完成。例如,常规函数调用不能一直持续到操作完成或某个时间段(以先到者为准)。这可以在javascript之外实现,并通过javascript公开(与同步ajax调用一样),但不能在具有常规函数的纯javascript中实现


与其他语言不同,Javascript是单线程的,因此当函数执行时,计时器永远不会执行(除了web workers,但它们的功能非常有限)。计时器只能在函数完成执行时执行。因此,您甚至不能在同步函数和计时器之间共享进度变量,因此计时器无法“检查”函数的进度

如果您的代码是完全独立的(没有访问任何全局变量,没有调用其他函数,也没有访问DOM),那么您可以在web worker中运行它(仅适用于较新的浏览器),并在主线程中使用计时器。当WebWorker代码完成时,它向主线程发送一条消息,其中包含它的结果。当主线程收到该消息时,它停止计时器。如果计时器在收到结果之前触发,它可能会杀死web工作者。但是,您的代码必须接受web工作人员的限制

Soemthing也可以通过异步操作完成(因为它们可以更好地处理Javascript的单线程特性),如下所示:

  • 启动异步操作,如ajax调用或加载图像
  • 使用
    setTimeout()
    作为超时时间启动计时器
  • 如果计时器在异步操作完成之前触发,则停止异步操作(使用API取消它)
  • 如果异步操作在计时器触发之前完成,则使用
    clearTimeout()
    取消计时器并继续
  • 例如,下面是如何在加载图像时设置超时:

    function loadImage(url, maxTime, data, fnSuccess, fnFail) {
        var img = new Image();
    
        var timer = setTimeout(function() {
            timer = null;
            fnFail(data, url);
        }, maxTime);
    
        img.onLoad = function() {
            if (timer) {
                clearTimeout(timer);
                fnSuccess(data, img);
            }
        }
    
        img.onAbort = img.onError = function() {
            clearTimeout(timer);
            fnFail(data, url);
        }
        img.src = url;
    }
    

    我不完全清楚你在问什么,但我认为Javascript没有按照你想要的方式工作,因此无法完成。例如,常规函数调用不能一直持续到操作完成或某个时间段(以先到者为准)。这可以在javascript之外实现,并通过javascript公开(与同步ajax调用一样),但不能在具有常规函数的纯javascript中实现


    与其他语言不同,Javascript是单线程的,因此当函数执行时,计时器永远不会执行(除了web workers,但它们的功能非常有限)。计时器只能在函数完成执行时执行。因此,您甚至不能在同步函数和计时器之间共享进度变量,因此计时器无法“检查”函数的进度

    如果您的代码是完全独立的(没有访问任何全局变量,没有调用其他函数,也没有访问DOM),那么您可以在web worker中运行它(仅适用于较新的浏览器),并在主线程中使用计时器。当WebWorker代码完成时,它向主线程发送一条消息,其中包含它的结果。当主线程收到该消息时,它停止计时器。如果计时器在收到结果之前触发,它可能会杀死web工作者。但是,您的代码必须接受web工作人员的限制

    Soemthing也可以通过异步操作完成(因为它们可以更好地处理Javascript的单线程特性),如下所示:

  • 启动异步操作,如ajax调用或加载图像
  • 使用
    setTimeout()
    作为超时时间启动计时器
  • 如果计时器在异步操作完成之前触发,则停止异步操作(使用API取消它)
  • 如果异步操作在计时器触发之前完成,则使用
    clearTimeout()
    取消计时器并继续
  • 例如,下面是如何在加载图像时设置超时:

    function loadImage(url, maxTime, data, fnSuccess, fnFail) {
        var img = new Image();
    
        var timer = setTimeout(function() {
            timer = null;
            fnFail(data, url);
        }, maxTime);
    
        img.onLoad = function() {
            if (timer) {
                clearTimeout(timer);
                fnSuccess(data, img);
            }
        }
    
        img.onAbort = img.onError = function() {
            clearTimeout(timer);
            fnFail(data, url);
        }
        img.src = url;
    }
    

    只有使用一些核心技巧才能实现这一点。例如,如果您知道函数返回什么类型的变量(请注意,每个js函数都返回一些东西,默认值是
    未定义的
    ),您可以尝试以下操作:定义变量

    var x = null;
    
    并在单独的“线程”中运行测试:

    最后运行函数:

    x = myFunction(myArguments);
    

    只有当您知道您的函数不返回任何值(即返回的值是
    未定义的
    )或它返回的值始终是“非false”,即未转换为
    false
    语句(如
    0
    null
    等)时,这才有效。

    您只能使用一些核心技巧来实现这一点。例如,如果您知道函数返回什么类型的变量(请注意,每个js函数都返回一些东西,默认值是
    未定义的
    ),您可以尝试
    
    execWithTimeout(function() {
        if (Math.random() < 0.5) {
            for(;;) {}
        } else {
            return 12;
        }
    }, 3000, function(err, result) {
        if (err) {
            console.log('Error: ' + err.message);
        } else {
            console.log('Result: ' + result);
        }
    });
    
    function execWithTimeout(code, timeout, callback) {
        var worker = new Worker('data:text/javascript;base64,' + btoa('self.postMessage((' + String(code) + '\n)());'));
        var id = setTimeout(function() {
            worker.terminate();
            callback(new Error('Timeout'));
        }, timeout);
        worker.addEventListener('error', function(e) {
            clearTimeout(id);
            callback(e);
        });
        worker.addEventListener('message', function(e) {
            clearTimeout(id);
            callback(null, e.data);
        });
    }
    
    export function callWithTimeout(func, timeout) {
      return new Promise((resolve, reject) => {
        const timer = setTimeout(() => reject(new Error("timeout")), timeout)
        func().then(
          response => resolve(response),
          err => reject(new Error(err))
        ).finally(() => clearTimeout(timer))
      })
    }
    
    export function sleep(ms) {
      return new Promise(resolve => setTimeout(resolve, ms))
    }
    
    const func1 = async () => {
      // test: func completes in time
      await sleep(100)
    }
    
    const func2 = async () => {
      // test: func does not complete in time
      await sleep(300)
    }
    
    const func3 = async () => {
      // test: func throws exception before timeout
      await sleep(100)
      throw new Error("exception in func")
    }
    
    const func4 = async () => {
      // test: func would have thrown exception but timeout occurred first
      await sleep(300)
      throw new Error("exception in func")
    }
    
    try {
      await callWithTimeout(func, 200)
      console.log("finished in time")
    }
    catch (err) {
      console.log(err.message)  // can be "timeout" or exception thrown by `func`
    }