javascript - jQuery Deferrable、Deferred 和 jQuery Deferred 之间的混淆

标签 javascript jquery jquery-deferred

我下载了一个名为 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、34 正在运行。

这似乎与没有 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/

相关文章:

javascript - 动态添加和删除帖子标题

javascript - Backbone + RequireJS - 等待创建另一个延迟对象的 Deferred

javascript - Jquery 延迟。多个 ajax 调用。延迟与异步假

javascript - 如何使用 JavaScript 在 SVG 中创建属性?

javascript - 如何将事件类添加到 html css 中的 li 元素

javascript - 如何创建动态弹出Jquery

javascript - jQuery 不适用于附加数据

javascript - jquery 通过文本选择选项无法正常工作

javascript - Deferred 和/或 Promise 数组的 jQuery.when() 进度

javascript - Vue.js 2.0 延迟加载