将参数传递给jquery延迟任务的设计模式

将参数传递给jquery延迟任务的设计模式,jquery,promise,Jquery,Promise,试着让我的头脑去处理延迟的任务。将以下功能作为承诺是否合法?我不想在ajax调用解决后立即采取行动——这还为时过早——而是在UI元素完全填充了ajax调用返回的数据时采取行动。成功回调中有一个循环 function populateCitiesDropdown( state ) { var dfd = new $.Deferred(); // ajax call to get cities for the specified state // ... // (

试着让我的头脑去处理延迟的任务。将以下功能作为承诺是否合法?我不想在ajax调用解决后立即采取行动——这还为时过早——而是在UI元素完全填充了ajax调用返回的数据时采取行动。成功回调中有一个循环

function populateCitiesDropdown( state ) {

    var dfd = new $.Deferred();

    // ajax call to get cities for the specified state
    // ...
    // (removed)
    // ...

    url:  "GetCitiesForSpecifiedState?state=" + state,

    // ...

    }).success ( function ( result, b, c) {

        // loop through result data
        //  populate Cities SELECT element
        // resolve when loop is finished
        dfd.resolve();

    });

    return dfd.promise();

}
如何在使用$时将状态参数传递给populateCitiesDropdown函数。何时

编辑其他背景:

需要使用多个ajax调用返回的数据填充多个下拉列表。每个任务由一个ajax数据获取和一个正在填充的SELECT组成。如果我只是将ajax调用传递给$。当:

              $.when(ajax1, ajax2, ajax3).done( function () { foo() ; });
然后,函数foo过早执行,即在填充SELECT元素之前。ajax调用在执行成功回调中的代码之前解析


当所有的下拉列表都被填充后(在所有ajax请求都被解决后的一段时间内发生),我将发出一个BindMainRecordtoUI调用

你在寻找比这更复杂的东西吗:

$.when( populateCitiesDropdown(xxx) ).done( function () ...
记住$.when不接受回调函数。这需要承诺。因此,您必须实际调用并执行populateCitiesDropdown函数,并可以在这样做时向其传递任何参数,它将立即作为参数返回承诺给$.when。这与.done或.then处理程序不同,后者实际上是回调,承诺代码稍后将调用它们

另外,请记住,如果您只有一个承诺,那么没有理由使用$.when,因为您可以将.done直接放在返回的承诺上

populateCitiesDropdown(xxx).done(function() {...});
美元.when的目的是一次管理多个承诺,而不仅仅是一个

而且,真的没有理由创建一个新的延迟。jQuery已经从ajax调用返回了一个承诺,因此您可以直接使用该承诺:

function populateCitiesDropdown( state ) {

    return $.ajax({...    

    // ajax call to get cities for the specified state
    // ...
    // (removed)
    // ...

    url:  "GetCitiesForSpecifiedState?state=" + state,

    // ...

    }).then ( function ( result, b, c) {

        // loop through result data
        //  populate Cities SELECT element
        // resolve when loop is finished

    });

}

而且,您应该切换到.then而不是.success as.。success已被弃用,.then是标准的承诺方式。

您的想法是正确的,但您的实现可以改进。还有许多其他方法可以做同样的事情;这只是一个例子

function populateCitiesDropDown(state) {
  var defer = $.Deferred(function (dfd) {
    $.get('GetCitiesForSpecifiedState', { state: state })
      .done(function (data) {
        // do stuff with returned data
        dfd.resolve('populateCitiesDropDown: loaded');
      })
      .fail(function () {
        dfd.resolve('populateCitiesDropDown: server error');
      });
  });

  return defer.promise();
}
那么你可以这样称呼它:

populateCitiesDropDown('TX').done(function (result) {
  console.log(result);
});

$。当PopulateCities下拉列表不能满足您的期望时。只需使用PopulateCities下拉列表…然后…!另外,不要在您的populateCitiesDropdown函数中使用。对于ajax调用,您已经有了一个承诺。@Bergi,但我希望操作不是在ajax获取完成时发生,而是在SELECT ui元素填充了ajax调用返回的数据时发生。那么?只需输入并返回填充的select元素的承诺。是的,有多个承诺-六个下拉列表。我没有意识到我可以在when中传递参数。@Tim:实际上你需要这样做,否则你会得到函数的承诺,并且不会进行ajax调用。@Tim-好的,如果你有多个承诺,可以使用$。我还为您的populateCitiesDropdown函数添加了一个简化。不需要在那里创建自己的延迟。只使用jQuery已经返回的那个。@jfriend00:我喜欢你的返回。ajax。。。明天我回到办公室后会做更多的测试。我在链接a时没有得到预期的结果。然后。。。在其中,我更新了循环中的UI元素。谢谢,当您可以使用jQueryAjax已经返回的内容时,没有理由在这里创建另一个延迟。我想你们误解了我的问题。我等待的解决方案不是ajax调用的完成,而是用ajax调用返回的数据填充SELECT UI元素的循环的完成。当下拉列表全部填充后,我想将主记录绑定到UI。将主记录绑定到UI必须等到下拉列表准备就绪。我看不出我的数据绑定函数如何知道“处理返回的数据”任务何时完成。@Tim-它们将被链接。然后处理程序和它们按顺序执行。第二个函数在第一个函数返回时调用其回调函数。承诺就是这样起作用的。如果第一个函数返回了一个承诺,而您没有在这里执行,那么第二个函数将被链接。在新的承诺本身得到解决之前,不会调用处理程序。这不是您必须知道的一个复杂问题,而是chained.then处理程序的另一个功能。@Tim我假设将state cities添加到您的select UI是一个顺序for循环,正当所以…您在循环完成后解析承诺,dfd.resolve,这就是我的示例所说明的。
populateCitiesDropDown('TX').done(function (result) {
  console.log(result);
});