2015-09-09 62 views
1

我有一個需要請求的JS資源數組。順序必須保持不變,並且響應必須按照我請求它們的順序進行。以下順序請求每個請求,但是我無法捕獲整個請求中的.done()promise回調。

我稱之爲getScripts方法從我的對象:

var depArray = ['file1.js', 'file2.js', 'file3.js']; 
getScripts(depArray, global_config.jspath + "/"); 

這一個迭代$ .Deferred內的陣列()嵌套$。當承諾過......

getScripts : function(arr, path) { 
     var depMap = []; 
     $.Deferred(
      $.map(arr, function(src) { 
       $.when(
        $.ajax({ 
          url: (path || "") + src + ".js", 
          success: function (data) { 
           depMap.push(data); 
           //return data; 
          } 
         } 
        ) 
       ).then(function() { 
        console.log("request complete...", (path || "") + src + ".js"); 
        return true; 
       }); 
      }) 
     ).done(
      function() { alert('completely done!!!!'); } 
     ); 
    }, 

警報('完成!!!!')立即被觸發,而不是等待ajax調用執行完成。我需要從方法中返回depMap數組,所以我有一個來自調用的所有響應的映射。

他們的迴應是:

['contents from file1.js', 'contents from file2.js', 'contents from file3.js'] 

但我永遠不會有一個depMap在年底手頭寬裕。承諾對我仍然有點困惑。任何幫助表示讚賞...

+0

呃,'$ .Deferred'不採取'undefined's作爲它的參數數組? – Bergi

回答

2

好的,一些清理是必要的。首先,刪除$.Deferred - 這是不需要的,因爲你已經有$.when的承諾。然後你需要構建一系列的承諾,並將其傳遞給$.when

最後,它可以是這樣的:

getScripts: function(arr, path) { 
    // map each promise to its resource and aggregate 
    return $.when.apply(null, arr.map(function(src) { 
     return $.ajax({url: (path || "") + src + ".js"}); 
    })).then(function(){ 
     return [].map.call(arguments, function(x){ return x[0]; }) // just the data 
    }); 
} 

演示:http://plnkr.co/edit/DvBj9PcaTQzskCRIUAHZ?p=preview

+0

不能保證ajax調用將按照它們被調用的順序返回,所以你的答案中的代碼不能保證'depMap'數組中項目的順序。 –

+0

是的,很好。我最初想用真實的承諾發佈答案,這就是爲什麼我這樣寫的,沒有解決它的jQuery。 – dfsq

+0

「真實的承諾」?你是否指的是來自不同圖書館的承諾? –

1

$.ajax()函數返回一個jqXHR對象,這是一個承諾。函數$.when()表示它需要一個或多個Deferred對象,但它似乎要求它們只是Promises,而不是完整的Deferred對象。因此,您不需要使用$.Deferred()爲每個ajax請求創建Deferred對象。您可以使用由$.ajax()返回的對象。您可以使用$.map()創建一個承諾數組,按照ajax調用的順序進行。

但最終,getScripts()函數不能返回depMap數組,因爲它是異步的。相反,它可以寫成返回一個Promise,如下所示。

getScripts: function(arr, path) { 
    return $.when.apply($, $.map(arr, function(src) { 
     return $.ajax({ url: (path || '') + src + '.js' }); 
    })).then(function() { 
     return (arr.length > 1) 
      ? $.map(arguments, function(a) { return a[0]; }) 
      : [arguments[0]]; 
    }); 
}, 

有關如何從$.when(...).then()函數返回的數組從參數到它的回調函數構造的信息,請參閱this Stackoverflow answer。 (對於.done()同樣的信息適用於.then()

Demo on jsfiddle