web-dev-qa-db-fra.com

appel synchrone et asynchrone dans angularJS avec promesse et report

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. 

Manette

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

Un service

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;
        }
    };
});
4
Paresh Gami

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

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

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

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>'  
              });
         }
    };
});
1
arci gaming