J'ai créé le contrôleur suivant avec 2 appels de service avec services. La deuxième réponse vient avant alors en premier. Je veux faire comme j'ai besoin de première réponse en premier et deuxième réponse en second. mais je viens de rester avec async et sync, aidez-moi s'il vous plaît à résoudre.
Le deuxième appel dépend du premier appel. Par exemple, si le premier appel renvoie un enregistrement 10, je dois appeler le deuxième service Web 10 en prenant le temps de la première réponse. donc j'utilise pour la boucle mais ce n'est pas correct.
var mycompaigndata = [];
asyncService.loadDataFromUrls($http.get(WSURL + 'api/first/',
{
headers:
{
"Authorization":'Bearer <my-token>'
}
}))
.then(function(data)
{
console.log(data);
});
asyncService.loadDataFromUrls($http.get(WSURL + 'api/second',
{
headers:
{
"Authorization":'Bearer <my-token>'
}
}))
.then(function(data)
{
console.log(data);
});
app.service('asyncService', function($http, $q)
{
return {
loadDataFromUrls: function(url)
{
var deferred = $q.defer();
var urlCalls = [];
urlCalls.Push(url);
$q.all(urlCalls)
.then(
function(results)
{
deferred.resolve(results)
},
function(errors)
{
deferred.reject(errors);
},
function(updates)
{
deferred.update(updates);
});
return deferred.promise;
}
};
});
Pour vous assurer que les deuxièmes appels sont exécutés une fois le premier terminé, placez le deuxième appel dans la variable then
du premier appel. Pour émettre plusieurs «seconds» appels en fonction du nombre de résultats du premier appel, utilisez $q.all
.
asyncService.loadDataFromUrls('api/first/')
.then(function(firstData) {
//assuming firstData is an array of 'x' items, do a call for each of these items:
console.log('results of first call holds ' + firstData.length + ' items');
var promises = [];
for(var i = 0; i<firstData.length; i++){
var id = firstData[i].id;//you can use this to pass to the second call
promises.Push(asyncService.loadDataFromUrls('api/second'));
}
return $q.all(promises);
})
.then(function(results) {
//'results' is an array of results, the nth item holds the result of the 'nth' call to loadDataFromUrls
for(var i = 0; i<results.length; i++){
console.log('result nr. ' + i + ' :' + results[i])
}
});
En utilisant return $q.all(promises)
, vous évitez la pyramide de promesses de Doom et conservez une structure plate.
Votre code de service n'a plus besoin de boucler. En résumé, vous pouvez raccourcir le code du service et éviter d'utiliser "l'antipattern de construction de promesse explicite" (voir ici ) comme ceci:
app.service('asyncService', function($http, $q)
{
return {
loadDataFromUrls: function(url)
{
return $http.get(WSURL + url, {
headers: {
"Authorization": 'Bearer <my-token>'
}
}).then(function(response){ return response.data; });
}
};
});
mettre la deuxième demande dans la promesse de la première demande:
var mycompaigndata = [];
asyncService.loadDataFromUrls($http.get(WSURL + 'api/first/',
{
headers:
{
"Authorization":'Bearer <my-token>'
}
}))
.then(function(data)
{
asyncService.loadDataFromUrls($http.get(WSURL + 'api/second',
{
headers:
{
"Authorization":'Bearer <my-token>'
}
}))
.then(function(data)
{
console.log(data);
});
});
Votre asyncService
semble totalement inutile et inutile.
Il semble que vous ayez juste besoin d'apprendre à enchaîner les promesses et à utiliser $q.all
correctement:
function queryApi(subUrl) {
return $http.get(WSURL + subUrl, {
headers: {
"Authorization":'Bearer <my-token>'
}
}).then(function (result) { return result.data; });
}
queryApi('api/first/')
.then(function (data) {
return $q.all(data.map(function (entry) {
return queryApi('api/second/' + entry.id);
}));
})
.then(function (results) {
console.log(results);
});
Je pense que la meilleure réponse est d'utiliser la boucle car vous devez itérer la réponse pour obtenir l'identifiant.
asyncService.loadDataFromUrls(WSURL + 'api/first/')
.then(function(data) {
//iterate to get the id
//call service again
asyncService.loadDataFromUrls(WSURL + 'api/first/')
.then(function(data) {
//code here
});
});
Un service
app.service('asyncService', function($http, $q) {
return {
loadDataFromUrls: function(url) {
return $http.get(url, {
"Authorization":'Bearer <my-token>'
});
}
};
});