2014-07-06 108 views
1

我有一個類似於下面的函數:處理Deferrred與異步AJAX調用

function refreshData() { 
    service.getSettings().done(function (settings) { 
     // DATA 1 
     service.getData1(settings).done(function (result) { 
      // do something local with result 
      // partial resolve 1 
     }); 
     // DATA 2 
     var localData = service.getLocalData(); 
     if (localData.length) { 
      service.getData2(settings, localData).done(function (result) { 
       // do something local with result 
       // partial resolve 2 
      }); 
     } else { 
      $('#list').empty(); 
      // or partial resolve 2 
     } 
    }); 
} 

我想要做的就是創建此功能,所以一個Deferred對象我知道什麼時候該數據刷新完全完成。我知道我可以用$.when將它們連在一起,但我希望兩個AJAX調用獨立運行,我不在乎一個是否在另一個之前完成。

我已經在上面標記了每件要解決的問題。我只是不知道如何完成這一點。

我的最終目標會是這樣一個電話:

refreshData().done(function() {  
    // hide loader 
}); 

回答

2

如何對這樣的事情,

function refreshData() { 
    var def1 = $.Deferred(); 
    var def2 = $.Deferred(); 

    service.getSettings().done(function (settings) { 
     service.getData1(settings).done(function (result) { 
      def1.resolve(result); 
     }); 
     var localData = service.getLocalData(); 
     if (localData.length) { 
      service.getData2(settings, localData).done(function (result) { 
       def2.resolve(result); 
      }); 
     } else { 
      $('#list').empty(); 
      def2.resolve(); 
     } 
    });  

    // return aggregated promise 
    return $.when(def1, def2); 
} 


refreshData().done(function(r1, r2) {  
    // hide loader 
}); 

注:未經檢驗

+0

您需要'def1'和'def2'獨立deferreds。不能使用像你這樣的同一個人。也許也可以使用現有的承諾,而不是創建新的承諾。 – jfriend00

+0

@ jfriend00謝謝隊友,我知道會有比這更好的解決方案,但當時並沒有打動我。 * Roamer-1888的*實際上是優雅的。編輯ans以指定單獨的延期。 –

2

你需要做的主要事情是:

  • 返回由$.when(partial1, partial2)
  • 生成後生成複合的承諾(和返回),其鏈接到你的外一.then()service.getSettings()

您也可能希望諧音的故障可觀察到的內部承諾,爲至少調試。

function refreshData() { 
    return service.getSettings().then(function (settings) {//note `return` and `.then()` 
     var partial1, partial2; // declare two promises 

     // utility function make error observable - avoids repetition below 
     function handleError(err) { 
      console.error(err); 
     }); 

     partial1 = service.getData1(settings).done(function (result) { 
      //do something local with result 
     }).fail(handleError);//make failure of partial1 observable 

     var localData = service.getLocalData();//assume this is synchronous 
     if (localData.length) { 
      partial2 = service.getData2(settings, localData).done(function (result) { 
       //do something local with result 
      }).fail(handleError);//make failure of partial2 observable 
     } else { 
      partial2 = $('#list').empty().promise();//sneaky way to generate a resolved promise 
     } 

     return $.when(partial1, partial2);//as we are inside a `.then()`, the promise generated here is effectively returned by refreshData(). 
    }); 
} 

看到代碼中的註釋

電話如下:

refreshData().done(function() {  
    // hide loader 
}).fail(function(err) { 
    // indicate failure 
}); 
+0

+1使用已有的承諾,而不是創建新的延期。 – jfriend00