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

How to make http request with nested loop

在我的应用程序中,我必须在嵌套循环中发送 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 数组(内循环)发送并行请求。我对 angular 很陌生,有没有其他方法可以做到这一点?

你可以这样做,一个小问题是你需要用 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

实现您的目标的一个很好的工具是 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']);

希望对您有所帮助。