8

我试图了解 deferred 是如何工作的,所以他们都使用setTimeout.

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

这个问题的一个例子使用setTimeout

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

在循环中调用函数之间有什么不同setTimeoutcallback();callback.call();

4

4 回答 4

13

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

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

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

尽管这可能会延迟callback()自己立即被调用,但这可能对您网站的整体性能有好处:

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

于 2013-08-29T11:26:53.233 回答
2

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 应该结束当前执行。

在当前执行期间有多少时间并不重要,因为它必须在执行另一个任务之前结束。

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

于 2013-08-29T11:25:37.150 回答
2

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

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

于 2013-08-29T11:22:03.650 回答
1

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

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

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

于 2013-08-29T11:28:24.487 回答