Le promesse di AngularJS, $ q, differiscono

MODIFICARE

La prima risposta è quella elegante, ma, come affermato alcune volte in questa domanda e in altre domande su StackOverflow, il problema è che il servizio e il controller eseguono il loro compito prima che i dati arrivino effettivamente.

(Ultimo commento sulla prima risposta 🙂

Sì, il problema è che le chiamate API terminano DOPO che il servizio viene eseguito e restituisce tutto al controller, vedi qui screencast.com/t/uRKMZ1IgGpb7 … Questa è la mia domanda BASE, come posso aspettare su tutte le parti per i dati arrivo?

È come se lo ripetessi ripetutamente, come facciamo un servizio che popola l’array dopo il corretto recupero dei dati, e il controller che riceve i dati dopo che tutto ciò accade , perché come puoi vedere nel mio screenshot, le cose girano in un altro ordine.


Ho questo codice:

var deferred = $q.defer(); $http.get('../wordpress/api/core/get_category_posts/?category_id=14 ').success(function(data) { //we're emptying the array on every call theData = []; catName = data.category.slug; theData = data; theData.name = catName; aggregatedData.push(theData); }); $http.get('../wordpress/api/core/get_category_posts/?category_id=15 ').success(function(data) { theData = []; catName = data.category.slug; theData = data; theData.name = catName; aggregatedData.push(theData); }); $http.get('../wordpress/api/core/get_category_posts/?category_id=16 ').success(function(data) { theData = []; catName = data.category.slug; theData = data; theData.name = catName; aggregatedData.push(theData); }); $http.get('../wordpress/api/core/get_category_posts/?category_id=17 ').success(function(data) { theData = []; catName = data.category.slug; theData = data; theData.name = catName; aggregatedData.push(theData); }); //deferred.resolve(aggregatedData); $timeout(function() { deferred.resolve(aggregatedData); }, 1000); /*//deferred.reject('There is a connection problem.'); if (myservice._initialized) { $rootScope.$broadcast('postsList', deferred.promise); }*/ //myservice._initialized = true; myservice = deferred.promise; return deferred.promise; 

Per la vita di me non riesco a capire perché devo mettere un timeout quando si passa l’array risultante a differire?

Se il principio non è come, differire aspetta che l’informazione arrivi e restituisce la promise? Qual è il punto di quel 1 secondo lì? Da quello che capisco, differire dovrebbe essere in grado di aspettare il tempo necessario all’API per restituire il risultato e restituire i dati promessi.

Sono davvero confuso, ho sbattuto la testa contro i muri per le ultime due ore perché non stavo ricevendo alcun dato nel mio controller, solo quando ho messo il timeout lì.

IMHO Penso che ci sia un modo molto intelligente (ed elegante) per farlo con $q.all .

Si prega di dare un’occhiata al codice qui sotto.

Suppongo che tu voglia restituire i dati contemporaneamente con tutti i risultati aggregati su un grande array.

 var myApp = angular.module('myApp', []); myApp.factory('myService', function ($http, $q) { return { getAllData: function () { return $q.all([ $http.get('../wordpress/api/core/get_category_posts/?category_id=14'), $http.get('../wordpress/api/core/get_category_posts/?category_id=15'), $http.get('../wordpress/api/core/get_category_posts/?category_id=16'), $http.get('../wordpress/api/core/get_category_posts/?category_id=17') ]).then(function (results) { var aggregatedData = []; angular.forEach(results, function (result) { aggregatedData = aggregatedData.concat(result.data); }); return aggregatedData; }); } }; }); 

Puoi vedere sopra che i dati aggregatedData vengono generati solo una volta che tutte le chiamate asincrone sono state completate tramite $q.all .

Devi solo includere il servizio come dipendenza in uno dei tuoi controllori, per esempio, e chiamare il servizio come questo myService.getAllData()

Spero che mi aiuti o fammi sapere se hai bisogno di un esempio operativo completo e posso fornirne uno! 🙂

Le chiamate $http.get sono asincrone, ma non stai aspettando che siano tutte completate prima di risolvere il differimento. Qui funziona con il timeout semplicemente perché sei fortunato che le chiamate abbiano il tempo di completare entro 1 secondo, tuttavia questo non è affatto affidabile.

Non ripeterò una soluzione completa qui, ma dare un’occhiata alla mia risposta per un altro problema simile.