我下载了一个名为jsdeferred的库来尝试帮助我解决一些代码流问题,但由于它的示例和...“文档”在某些方面还不清楚,我有点迷失了。但是当我继续阅读和挖掘,当然还要在阳光下搜索所有内容时,我还发现jQuery有自己的Deferred()系统。为了适当的上下文,我将两者都链接到这里。

Link to jsDeferred Library

Link to jQuery.Deferred()

问题

我需要找到一种方法告诉页面“坚持到完成最后一件事情”。

这就是jsdeffered的想法。因此,我的问题之一是问我应该使用哪个? jsDeferred或jQuery.Deferred();然后按照我在下面概述的方式使用它。

情况

简而言之,这是我需要执行以下行为的情况。


页面加载时,定义了view model


这是使用kendo ui mvvm声明我的视图模型,因此它是一个kendo.data.ObservableObject


对数据库进行$.ajax调用以获取一些默认模型数据


这是我最麻烦的地方。在完成此$.ajax之前,我需要一切“保持”。但是如果可以的话,我不想将所有内容包装在$.ajax().done(r)中。在我看来,这太草率了,有时让人感到困惑。


呈现页面上的其他小部件,它们具有通过kendo ui Remote DataSource完成的相应数据库查询。


这些实际上按预期工作。


jQuery Validate连接到视图,并且已经设置了默认值。


这也按预期工作。


调用kendo.bind('body', viewModel);进行模型绑定。


现在这是我遇到麻烦的地方,回到step 2进行调用的地方。一直在发生的事情是在$.ajax完成之前触发了kendo.bind。我可以将其放在$.ajax函数中,并且对于这个确实可以工作的特定页面,但是在许多其他情况下,这不合适。

我尝试过的

首先,我很清楚$.ajax({}).done();文档对我来说还不清楚,因为逐字运行其示例实际上是行不通的。我不断被告知jsdeferred之类。我最终发现,在第一次调用next is not defined之前,您必须具有隐式的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);
});


我相信,当上一个完成时,它们将一个接一个地运行。但这不是正在发生的事情。 nextSTEP 1运行时,STEP 2, 3仍在获取过程中。

这似乎与没有4库的代码的运行方式没有什么不同。所以我很困惑,绝对希望在这里有所帮助。基本上,我需要在jsdeferred触发之前完全完成STEP 1

最佳答案

问题是next()希望您返回想要它等待的东西。在第一步中,您不返回任何东西。因此,jsdeferred假设您正在执行同步操作(已经完成),因此继续执行步骤2。

而是,返回从jQuery.Deferred()调用返回的$.ajax()。然后,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.
});

10-08 16:24