2017-10-11 158 views
3

HTTP請求在我的申請,我必須在一個嵌套循環發送一個HTTP請求,因爲我展示如下:如何使嵌套循環

for(let i=1;i<Names.length;i++) { 
    for(let k=1;k<Data.lenght;k++) { 
     let url = hostPath + "/"+Names[i] + "/" + Data[i]; 
     this.http.get(url); 
    } 
} 

我上面的要求如下所述的方式來完成:

for(let i=1;i<Names.length;i++) { 
    Observable.from(Data).ConcatMap((data) => { 
     let url = hostPath + "/" + Names[i] + "/" + data; 
     this.http.get(url); 
    }).subscribe(() => {}) 
} 

我希望保持與關於所述Names陣列(外環)以正確的順序,而是可以發送對Data陣列(內環)並行請求。我對角度很陌生,有沒有其他方法可以做到這一點?

+2

更好地收集你需要的所有數據請求,然後用它發出一個請求 – DanilGholtsman

+0

@DanilGholtsman任何建議怎麼做? – HardRocker

+0

你的意思是並行運行來自'Names'的所有迭代請求和來自'Data'的所有迭代請求並行運行給定名稱? –

回答

2

你可以做到這一點,一個小問題是你需要處理空數組defaultIfEmpty。以下代碼也可以處理:

let allData$ = Names.map(name => Observable.forkJoin(
    Data.map(d => { 
     const url = hostPath + '/' + name + '/' + d; 
     return this.http.get(url); 
    })).defaultIfEmpty([]); 
); 

Observable.forkJoin(allData$).defaultIfEmpty([]).subscribe(); 
// You will get data in same order here 
+0

面臨一個問題,當任何中間請求失敗時,隨後的請求將被取消。如何避免它。 我還沒有添加「defaultIfEmpty([]);」因爲它顯示錯誤,因爲方法不可用於Observable。 我的應用程序是Angular 2應用程序。 – HardRocker

+0

這很容易處理,你可以把你的電話接通並處理那裏的錯誤。例如,這一行返回this.http.get(url).catch(error => Observable.of(undefined))。 –

+0

這對你有用嗎? –

0

實現您的目標的一個很好的工具是JavaScript異步函數。提出的解決方案建議兩個功能:第一發送Data承諾在平行和第二順序使用並行Data那些發送Names承諾:

/** 
 
* Sends the Data promises in parallel and returns the promise 
 
* 
 
* @param {string} param the name from the Names array 
 
* @param {array} array the Data array 
 
* @returns {promise} 
 
*/ 
 
function processParallel(param, array) { 
 
    return Promise.all(array.map((element) => { 
 
     // make sure to call $http and hostPath correctly here because of 
 
     // the function scope change 
 
     let url = `${hostPath}/${param}/${element}`; 
 
     return $http.get(url); 
 
    })); 
 
} 
 

 
/** 
 
* Sends the Names promises sequentially 
 
* 
 
* @param {array} firstArray the Names array 
 
* @param {array} secondArray the Data array 
 
*/ 
 
async function processSequential(firstArray, secondArray) { 
 
    for (let i = 0; i < firstArray.length; i++) { 
 
     await processParallel(firstArray[i], secondArray); 
 
    }; 
 
}

從而可以調用它們如下:

processSequential(Names, Data); 

您可以在此簡化示例中測試此解決方案:

const hostPath = '/home'; 
 
function processParallel(param, array) { 
 
    return Promise.all(array.map((element) => { 
 
     let url = `${hostPath}/${param}/${element}`; 
 
     return new Promise((resolve) => { 
 
      setTimeout(() => { 
 
       console.log(url); 
 
       resolve(); 
 
      }, 500); 
 
     }); 
 
    })); 
 
} 
 
async function processSequential(firstArray, secondArray) { 
 
    for (let i = 0; i < firstArray.length; i++) { 
 
     await processParallel(firstArray[i], secondArray); 
 
    }; 
 
} 
 
processSequential(['John', 'Sarra', 'Marie'], ['1', '2', '3']);

希望這有助於。