【问题标题】:Assigning the deferred object (jqxhr) to the model or collection将延迟对象 (jqxhr) 分配给模型或集合
【发布时间】:2013-01-03 15:56:05
【问题描述】:

我正在开发一个 Backbone 应用程序,并且复杂性正在增加。副作用之一是有时页面的初始加载速度很慢。我已经将此问题追溯到 AJAX 请求等待。

在我当前的一些路线中,我提出了 4 个单独的请求。有些是重要的,例如加载模板。因此,我使用 jQuery ajax 请求中的 done() 函数来传递继续加载页面的回调。

有时我需要一个无关紧要的小元素的数据。例如,加载最后 5 篇博文的请求。 现在我的想法是,我想尽快发出请求,而不会停止其余路由的执行,我想知道它什么时候准备好。

这是我的建议

var myModel = new Posts(); //instantiate the model
myModel.dfd = myModel.fetch();

然后在处理最后一个帖子元素的子视图中具有将模型传递给的方法并执行类似的操作

render : function() {
  var self = this;
  this.model.dfd.done(function( ) {
    this.html( template( self.model.toJSON() );
  }
} 

这个想法是,如果请求已经完成,它将立即执行,如果没有,它将等待。但至少我从节省时间中受益,直到它达到这一点。

这是个好主意吗?

【问题讨论】:

  • 能否包含初始化视图并调用render() 方法的代码?
  • “这是个好主意吗?”。你告诉我们。有用吗?
  • @Beetroot-Beetroot 是的,它工作正常。但还不确定我获得了多少性能优势。
  • 如果你想要好的页面加载分析,那么试试 Opera 的 Dragonfly。 FF 的 Firebug 也可以这样做;我不确定,因为我不使用 FF。

标签: jquery backbone.js jquery-deferred


【解决方案1】:

我喜欢 promises 和 deferred,我认为它们很棒,但我不认为这是使用它们的地方。而是让模板能够呈现 UI 的默认版本,即使模型尚未填充。所以无论我们是否从服务器检索到模型的数据,视图总是做同样的事情。

因此,他们可能会在从服务器检索它们所需的几分之一秒内看不到博客条目(模板和仅返回 {} 的 model.toJSON() 调用的乘积)。然后,当模型填充数据并触发其“更改”事件(我假设您有视图监听模型的更改事件并在它发生时进行渲染)时,它会自动更新。

我认为这是 Backbone.js 中最优雅、最自然的处理方式。它使代码保持干净,它可以处理视图和模型完成操作的任何排序,而无需借助特殊编码来尝试和排序操作。

我认为使这种安排更优雅的唯一一点是,如果您还监听模型上的“请求”事件并向最终用户显示某种忙碌指示符,直到触发“同步”事件。那么用户不仅最初会看到 UI 更新,如果尚未检索到最终数据,他/她就知道等待,因为请求处于未决状态。

【讨论】:

  • 这在可用性方面似乎也是一种流行的方法。例如Facebook 手机将首先加载一些缓存的内容,直到它获取一些新的更新。 Instagram 也是如此。
【解决方案2】:

这完全可行,这是利用$.Deferreds 的一个很好的例子……但您还可以考虑另一种方法:首先使请求同步。

Fetch 将其选项传递给$.ajax$.ajax 采用一个“异步”参数来控制请求是同步的还是异步的。这意味着如果你这样做:

self.model.fetch({async: false});
// self.model will already be fetched by the time this next line runs
this.html( template( self.model.toJSON());

恕我直言,无论哪种方式都很好;哪种风格只是偏好问题。

附:关于后一种风格的一个小提示是,如果您尝试将其与 $.Deferred 结合使用,它可能会出现问题。来自 jQuery 网站:

从 jQuery 1.8 开始,不推荐使用 async: false 和 jqXHR ($.Deferred);您必须使用完成/成功/错误回调。

【讨论】:

  • “强烈建议不要将此选项设置为 false(从而使调用不再异步),因为它可能导致浏览器无响应。” - jQuery 文档
  • 对,但是如果你在做“A) 提出请求,B) 在请求返回之前不要做任何事情,C) 再做一些事情”,这与“A) 基本相同发出请求,B) 页面暂停,C) 再次执行”。
  • nod NM 我找到了(不在参数说明中,在说明文中埋没了)。不过,这一切都与上下文有关。他们警告你不要让你的页面在你搁置东西时任意变慢,但如果你想要搁置东西......他们有那个参数是有原因的。
  • 因为 JavaScript 是单线程的,如果你使用async: false,那么你实际上是在告诉浏览器,“在这个请求返回之前不要处理任何 JavaScript!”这意味着如果页面上有任何其他 JavaScript 处理程序,它们也不会在请求返回之前执行。
  • 哪个可能仍然是您想要的效果,这取决于您的需要。然而,在重新阅读 OP 之后,听起来他们可能还有其他(JS)的东西在进行,所以也许这个替代方案对他们来说并不是最好的。为了真正确定,尽管我们确实需要查看更多他们的应用程序(而不是为此烦恼,向 OP 提供信息并让他们做出判断更有意义,所以感谢您提到这个重要的限制)。
猜你喜欢
  • 2011-09-11
  • 2012-09-06
  • 2018-12-20
  • 1970-01-01
  • 2018-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-13
相关资源
最近更新 更多