这里的setTimeout 0是解决什么问题呢

  if (!this.isShown()) {
    return;
  }
  this.$container.trigger('beforeHide.modal.cmp', {modal: this});
  this.$container.addClass(HIDE_CLS);
  setTimeout(function () {
    this.$container.trigger('afterHide.modal.cmp', {modal: this});
  }.bind(this), 0);
阅读 3.6k
7 个回答

完整代码大概是:

function hide(){
  if (!this.isShown()) {
    return;
  }
  this.$container.trigger('beforeHide.modal.cmp', {modal: this});
  this.$container.addClass(HIDE_CLS);
  setTimeout(function () {
    this.$container.trigger('afterHide.modal.cmp', {modal: this});
  }.bind(this), 0);

}

这里有一种情况,是 addClass 之后,对应的样式在 hide 执行完之前不会生效(只是有可能,各浏览器表现可能还不一样,除了 addClass 其它一些更改也是类似,如果你像我一样不想去管这里面的细节,类似情况,一个 setTimeout 也许就足以解决问题,比较偷懒的作法)。

那么,想要达到的一个效果,就像是说,“在 hide 函数执行完之后,尽快地去做另一件确定的事”,这个“尽快”,就是 setTimeout(f, 0) 的作用了,细节上,你确实是不知道“尽快”到底是什么时候, setTimeout 只是确保了这个地方有一个“上下文切换”(这里说的“上下文”跟 this 那东西不是一回事,指的是“异步”执行的环境)。

那么,在不考虑 addClass 效果的情况下,这个 setTimeout 是否多余呢?

如果单看 hide ,那么它是多余的。但是事实上,你还要看 hide 被调用时的上下文情况,这里的情况会比较复杂。一个现成的例子,是 angular 中的 $digest 调用。$digest调用如果是在一个被“监控”的上下文环境中的话,是会报错的,比如:

<div ng-click="test()">点击</div>
$scope.test = function(){
    $scope.$digest(); // 报错
}

套个 setTimeout 就没问题了:

$scope.test = function(){
    setTimeout(function(){
        $scope.$digest();
    }, 0);
}

总的来说, setTimeout(f, 0) 都是一种偷懒的,随意性的方法。

这是事件循环机制,当setTimeout的时候,他建立一个setTimeout的队列,会等到当前队列的任务执行完,再执行setTimeout队列的任务

setTimeout表示发起一个异步线程,尽管等待时间是0 它也得等同步代码执行完后。在下一个事件循环中执行。

除了异步的作用;
你这种场景下大多是为了等待DOM渲染完毕

等前面一堆事件队列做完再执行 不然执行逻辑混乱

变成异步执行

放入 callstack 底部

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题