【问题标题】:Why use setTimeout in deferred为什么在延迟中使用 setTimeout
【发布时间】:2013-08-29 11:17:35
【问题描述】:

我试图了解 deferred 的工作原理,所以他们都使用setTimeout

this.callbacks;// array of functions reference
this.callbacks.forEach(function(callback){
    window.setTimeout(function(){
          callback(data);
    },0);
});

来自this questions 的一个使用setTimeout 的示例

resolve: function (data) {
    this.promise.okCallbacks.forEach(function(callback) {
      window.setTimeout(function () {
        callback(data)
      }, 0);
    });
  },

setTimeoutcallback();callback.call();循环调用函数有什么区别

【问题讨论】:

    标签: javascript deferred


    【解决方案1】:

    这样做的原因是为了让 javascript 线程有机会触发可能在队列中等待的任何其他事件。

    Javascript 是单线程的。如果一个事件被触发,它只能在当前运行的代码完成后运行。

    使用具有零延迟的setTimeout 有效地告诉JS 解释器callback 函数调用是新上下文的一部分并且您当前的代码块已经完成。这意味着 JS 在调用callback() 之前会趁机检查是否有其他事件需要处理。

    虽然这可能会延迟 callback() 本身被立即调用,但这可能对您网站的整体性能有好处:

    可能需要处理的其他事件包括点击事件和其他 UI 触发器。如果您不给它们执行的机会,则可能会使您的用户界面显得迟缓或无响应。

    【讨论】:

      【解决方案2】:

      setTimeout 在时间过去后运行并且 JavaScript 进程是空闲的。

      使用call 将立即运行回调并阻止其他所有内容。

      【讨论】:

      • @Moein7tl:实际上超时有一个下限,大于 0(IIRC 对于流行的浏览器来说大约是 4 毫秒)。因此 0 意味着“一旦你可以解决它”。大概使用零超时的人知道这一点并故意这样做。
      • @Moein7tl — 是的,请注意,在我说“时间已经过去”之后,我说的是 “和”
      【解决方案3】:

      setTimeout(func,0) 不会立即被调用。

      它只是模拟一个带有回调的异步函数。

      function asyncFunc(callback) {
          console.log("step1");
          setTimeout(callback,0);
          console.log("step2");
      }
      
      asyncFunc(function() {console.log("async step")});
      /* output:
      step1
      step2
      async step
      */
      

      https://developer.mozilla.org/en-US/docs/Web/API/window.setTimeout

      由 setTimeout() 执行的代码在与调用它的函数不同的执行上下文中运行

      所以它在单独的执行上下文中运行,但在执行它之前,由于 javascript 在单线程上运行,javascript 应该结束当前执行。

      当前执行的时间长短并不重要,因为它必须在执行另一个任务之前结束。

      如果你在任务结束之前有一个无限循环,例如,你的回调永远不会被调用。

      【讨论】:

        【解决方案4】:

        setTimeout() 允许您注册一个函数,以便在经过指定的时间后调用一次。

        Window 对象的setTimeout() 方法安排一个函数在一个 指定的毫秒数。 setTimeout() 返回的值可以是 传递给clearTimeout()以取消计划函数的执行。

        如果你调用setTimeout()的时间为0毫秒,你指定的函数不会被调用 马上。相反,它被放置在一个队列中,以便在之后“尽快”调用 任何当前挂起的事件处理程序都完成运行。

        【讨论】:

          猜你喜欢
          • 2016-08-09
          • 2015-06-26
          • 1970-01-01
          • 2022-08-02
          • 1970-01-01
          • 2021-02-23
          • 1970-01-01
          • 2020-09-10
          • 1970-01-01
          相关资源
          最近更新 更多