1

我正在开发一个 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() );
  }
} 

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

这是一个好主意吗?

4

2 回答 2

2

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

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

我认为这是 Backbone.js 中最优雅、最自然的做事方式。它使代码保持整洁,并处理视图和模型完成操作的任何排序,而您不必求助于特殊编码来尝试和排序操作。

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

于 2013-01-03T22:04:52.223 回答
0

这将完全有效,这是利用$.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());

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

PS 关于后一种风格的一个小提示是,如果你尝试将它与 $.Deferred 结合起来,它可能会出现问题。从 jQuery 网站:

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

于 2013-01-03T18:08:16.273 回答