2017-10-11 130 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']);

希望这有助于。