【问题标题】:why does underscore defer fix so many of my issues?为什么 underscore defer 解决了我的很多问题?
【发布时间】:2013-03-07 12:25:39
【问题描述】:

在使用骨干网几周后,我意识到下划线延迟最终解决了我在渲染各种视图时遇到的许多异步问题。 有人可以帮我准确理解下划线 defer 的作用以及 $.ready() 或其他类型的等待 dom 呈现函数有何不同。使用它的缺点是什么?

_.defer = function(func) {
    return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
};

【问题讨论】:

  • 那么,_.delay 是做什么的?答案就在于此。
  • 它似乎要等待 1 毫秒。我仍然不明白它是如何知道某些元素被渲染等的。也许我使用不正确?
  • 如果您发布一个您必须使用defer 并且不明白原因的地方的示例可能会更有帮助。
  • 这一定是我最喜欢的关于 SO 的问题之一。 “这解决了我所有的问题,但我不知道”:D
  • 我注意到_.defer 会导致我的 Backbone 应用程序出现内存泄漏。因此,虽然它可以修复渲染问题,但它可以添加内存问题。将_.defer(_.bind(this.renderViews, this)); 替换为this.renderViews(); 将我的单页应用程序中随着导航而增长的堆配置文件数量减半。我认为这是因为它增加了在视图关闭时通过在自然顺序之外进行工作来搞砸资源取消引用的可能性。当然,这显然首先取决于您如何使用 Backbone。

标签: javascript backbone.js underscore.js


【解决方案1】:
# These are equivalent
_.defer(fn);
setTimeout(fn, 1);

所以defer 只是一毫秒的setTimeout(它还有一些更方便的功能,但这些在这里并不重要。)


JavaScript 有运行循环。它是单线程的,但它的执行基于事件或计时器开始和停止。每次您的 JS 引擎开始运行某些代码时,它都会开始其运行循环的一次迭代。

所以defer 所做的就是说“在下一个运行循环中运行这段代码”。

_.defer(function() { alert('after'); });
alert('before');

这会在“之前”和“之后”发出警报。这是因为当前的运行循环在“之前”结束了哪些警报,然后紧接着一个新的运行循环开始并运行“之后”警报的代码。

因此,只要您在这里有代码,但您希望它首先运行此代码之后的代码,那么您将使用defer

_.defer(functionToRunLast);
functionToRunFirst();

这对 DOM 来说很方便。有时您更改它,但更改不会立即解析或呈现。在 run loop 结束时,浏览器会赶上并解析和渲染 DOM,然后下一个 run loop 开始并可以与新渲染的 DOM 交互。

(究竟是什么情况导致了这种延迟的 DOM 解析,我不确定,但我过去在自己的项目中已经注意到它。)


不是准备好 DOM 的替代品。下一个运行循环可能发生在之前 DOM ready 触发,不要混淆这些概念。

【讨论】:

  • 我很确定 DOM 会立即更新,但渲染(以及因此的大小和定位之类的事情)通常要等到浏览器重新获得控制权之后才会发生;这就是为什么当您想将 Google 地图绑定到您刚刚添加的东西时,您经常需要 defer(或等效的 setTimeout):地图想知道事物有多大,但直到浏览器有机会计算它。
  • @whiteb0x 基本上是一样的。查看underscore source,您会看到defer 调用delay 的时间为1,而delay 调用setTimeout
  • 您的答案是正确的,尽管您所说的“循环”在技术上称为“消息”。消息被添加到队列中。事件循环处理每条消息,一次一条。当您调用 setTimeout 时,它会将回调放在队列的末尾。 developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/EventLoop
  • @PatrickMcElhaney MDN 上 EventLoop 的链接非常有帮助。
  • 有谁知道是否存在差异/原因下划线将超时设置为 1,而不是 0?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-10
  • 1970-01-01
  • 2014-06-21
  • 2017-08-26
  • 2010-09-21
  • 1970-01-01
相关资源
最近更新 更多