我下载了一个名为 jsdeferred
的库来尝试帮助我解决一些代码流问题,但我有点迷茫,因为它的示例和...“文档” 在某些事情上有点不清楚。但是当我继续阅读和挖掘,当然还有谷歌搜索阳光下的一切时,我还发现 jQuery 有它自己的 Deferred()
系统。为了适当的上下文,我在此处链接了两者。
Link to jsDeferred Library
Link to jQuery.Deferred()
问题
我需要找到一种方法来告诉页面“坚持到最后一件事完成”。
这就是 thought jsdeffered
所做的。所以我的部分问题是问我应该使用哪个? jsDeferred 或 jQuery.Deferred(); 然后是如何使用它,正如我在下面概述的那样。
情况
我的场景是这样的,简而言之,我需要执行以下行为。
- 页面加载,
View 模型
被定义
这是使用 kendo ui mvvm
来声明我的 View 模型,所以它是一个 kendo.data.ObservableObject
- 对数据库进行
$.ajax
调用以获取一些默认模型数据
这是我遇到最多麻烦的地方。在 $.ajax
完成之前,我需要一切“坚持”。但是,如果可以的话,我不想将所有内容都包装在 $.ajax().done(r)
中。这对我来说看起来/感觉起来很草率,有时会让人感到困惑。
- 呈现页面上的其他小部件,它们通过
kendo ui Remote DataSource
完成各自的数据库查询。
这些实际上按预期工作。
jQuery Validate
已连接到 View ,默认值已设置。
这也按预期工作。
kendo.bind('body', viewModel);
被调用以执行模型绑定(bind)。
现在这就是我遇到麻烦的地方,回到第 2 步
我进行 $.ajax
调用的地方。不断发生的是 kendo.bind
在 $.ajax
完成之前被触发。我可以将它放在 $.ajax({}).done();
函数中,对于确实有效的这个特定页面,但会有很多其他不适合的情况。
我尝试过的
首先,我要明确的是,jsdeferred
文档对我来说不是很清楚,因为逐字运行它的示例实际上并没有用。我不断地被告知 next is not defined
等等。我最终发现,在第一次调用 next
之前,您必须有一个隐式的 Deferred.
。
这就是我认为会发生的事情......
var viewModel = new kendo.data.ObservableObject({
// various view model properties defined
});
Deferred.define();
next(function() { // let's call this STEP 1
$.ajax({
// data for ajax to controller
}).done(function(result) {
// perform operations with result
});
}).
next(function() { // let's call this STEP 2
$('#dropdownlist_target').kendoDropDownList({
// parameters, remote data source for drop down list, etc.
}).data("kendoDropDownList");
}).
next(function() { // let's call this STEP 3
$('form').validate({
// any extra form validation stuff
});
}).
next(function(){ // let's call this STEP 4
kendo.bind('body', viewModel);
});
我相信当前一个完成时,它们会各自运行一个,紧接着另一个。但这不是正在发生的事情。 STEP 1
仍在获取过程中,而 STEP 2、3
和 4
正在运行。
这似乎与没有 jsdeferred
库的代码运行方式没有任何不同。所以我很困惑,绝对会在这里得到一些帮助。基本上,我需要在 STEP 2
触发之前完全完成 STEP 1
。
最佳答案
问题是 next()
希望您返回您希望它等待的东西。在第一步中,您不会返回任何东西。因此,jsdeferred
假设您正在执行同步操作(已经完成),因此它会继续第 2 步。
相反,返回从 $.ajax()
调用返回的 jQuery.Deferred()
。然后 jsdeferred 将等待它完成然后它执行第 2 步。
无论如何,我都会转储 jsdeferred
。正如您所意识到的,jQuery 具有完全成熟的 Deferred 实现。我不确定 jsdeferred 给聚会带来了什么。
使用 $.ajax().done(r)
一点都不马虎。异步行为是事件驱动语言的核心,JavaScript 就是其中之一。拥抱它,否则你会在生命的早期非常试图避免它。
如果你恢复到 jQuery 的 Deferred 实现,你可能会喜欢 then()
, 为您提供 next()
;
$.ajax({
// data for ajax to controller
}).done(function(result) {
// perform operations with result
}).then(function () {
$('#dropdownlist_target').kendoDropDownList({
// parameters, remote data source for drop down list, etc.
}).data("kendoDropDownList");
$('form').validate({
// any extra form validation stuff
});
kendo.bind('body', viewModel);
}).then(function () {
// Note you can chain then()'s as well.
});
关于javascript - jQuery Deferrable、Deferred 和 jQuery Deferred 之间的混淆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24286706/