2017-10-11 4 views
3

Dans mon application, je dois envoyer une requête HTTP dans une boucle imbriquée comme je montre ci-dessous:Comment faire une demande http avec boucle imbriquée

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); 
    } 
} 

je l'ai fait ci-dessus exigence de la manière décrite ci-dessous:

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

Je veux maintenir le bon ordre en ce qui concerne le tableau Names (boucle externe), mais peut envoyer la demande parallèle pour le réseau Data (boucle interne). Je suis très nouveau à angulaire, Y at-il un autre moyen de le faire?

+2

mieux de recueillir toutes les données dont vous avez besoin effectuer une demande sur, puis faire une demande avec lui – DanilGholtsman

+0

@DanilGholtsman une suggestion comment le faire? – HardRocker

+0

Voulez-vous dire exécuter toutes les requêtes d'itération de 'Names' de manière séquentielle et toutes les requêtes d'itération de' Data' pour un nom donné en parallèle? –

Répondre

2

Vous pouvez le faire, un petit problème est que vous devez gérer un tableau vide avec defaultIfEmpty. Le code suivant gère également:

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

face à un problème, lorsqu'une demande intermédiaire a échoué, les demandes suivantes sont annulées. comment l'éviter. Je n'ai pas ajouté "defaultIfEmpty ([]);" car il indiquait erreur comme méthode non disponible pour Observable. Mon application est Angular 2application. – HardRocker

+0

C'est facile à gérer, vous pouvez mettre un piège dans votre appel get et gérer l'erreur là-bas. Par exemple, cette ligne renvoie this.http.get (url) .catch (error => Observable.of (non défini)). –

+0

Cela a-t-il fonctionné pour vous? –

0

Un excellent outil pour atteindre votre objectif sont les fonctions asynchrones JavaScript. La solution proposée suggère deux fonctions: la première envoie les Data promesses en parallèle et le second envoie les Names promesses en utilisant successivement les Data parallèles les:

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

Vous pouvez les appeler ainsi comme suit:

processSequential(Names, Data); 

Vous pouvez tester cette solution dans cet exemple simplifié:

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

Hope this helps.