jQuery在ExecuteQueryAsync中承诺两次

时间:2014-03-03 14:16:22

标签: promise jquery-deferred

我正在尝试使用JavaScript从托管元数据服务获取术语,有些术语有子术语,所以我需要使用嵌套延迟(jquery promises)。以下是我的代码。

$.when(GetTerms()).done(function (topMenu) {
     myDoElement.html(topMenu);
});
function GetTerms(){
   var dfd = $.Deferred();
   var arr1 = [];
   //some variables and code here
   clientCtx.load(terms);
   clientCtx.executeQueryAsync(Function.createDelegate(this, function (sender, args) {
      var termsEnumerator = terms.getEnumerator();
      while (termsEnumerator.moveNext()) {
         // here adds som html using arr1.push("");
         var currentTerm = termsEnumerator.get_current();
         $.when(GetSubTerms(currentTerm)).done(function (childItemsHtml) {
             //adding sub terms
              arr1.push(childItemsHtml);
         });             
       }
       //push closing html elements into arr1
       dfd.resolve(arr1.join(''));
   }),
   Function.createDelegate(this, function (sender, args) {
     dfd.reject(args.get_message());
   }));
   return dfd.promise();
 }

 function GetSubTerms(parent) {
     var dfdChild = $.Deferred();
     var arr2 = [];
     var childs = parent.get_terms();
     clientCtx.load(childs);
     clientCtx.executeQueryAsync(Function.createDelegate(this, function (sender, args) {
         //adding som html to arr1 using push
         var childsEnumerator = childs.getEnumerator();
         while (childsEnumerator.moveNext()) {
             var childTerm = childsEnumerator.get_current();
             //pushing elements into arr2
         }
         //pushing closing html elements into arr2
         dfdChild.resolve(arr1.join(''));
     }),
     Function.createDelegate(this, function (sender, args) {
         dfdChild.reject(args.get_message());
      }));
     return dfdChild.promise();
 }

如果我不使用GetSubTerms,它适用于顶级术语(父母),它会返回所有父级,但问题是当我使用GetSubTerms时它只返回第一个父级。

1 个答案:

答案 0 :(得分:2)

while (termsEnumerator.moveNext()) {
   // here adds som html using arr1.push("");
   var currentTerm = termsEnumerator.get_current();
   $.when(GetSubTerms(currentTerm)).done(function (childItemsHtml) {
     //adding sub terms
     arr1.push(childItemsHtml);
   });             
}
//push closing html elements into arr1
dfd.resolve(arr1.join(''))

这不起作用。 GetSubTerms仍然是异步的,因此当{/ 1}}被调用时,arr1将不会包含childItemsHtml s 。在调用之前,您需要等待承诺完成!做这样的事情:

dfd.resolve()