如何使用嵌套循环发出http请求

时间:2017-10-11 12:42:31

标签: angular rxjs angular2-template

在我的应用程序中,我必须在嵌套循环中发送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 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

实现目标的一个很棒的工具是JavaScript异步函数。建议的解决方案提出了两个功能:第一个并行发送Data个承诺,第二个使用并行Names顺序发送Data个承诺:

&#13;
&#13;
/**
 * 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);
    };
}
&#13;
&#13;
&#13;

您可以按如下方式调用它们:

processSequential(Names, Data);

您可以在此简化示例中测试此解决方案:

&#13;
&#13;
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']);
&#13;
&#13;
&#13;

希望这有帮助。