i using angular's $q execute multiple $http post calls asynchronously. working nicely , calls returning @ same time, within few milliseconds.
the problem next step process results. want results processed in parallel seem queuing , process 1 @ time.
i've pasted code below , appreciate if can point me in right direction how ensure results processed in parallel. code searchservice , 'search' method entry point controller.
var searchservice = { searchoptions: {}, searchresults: { foos: [], bars: [], typebs: [], typeas: [] }, searchfacets: { foos: [], bars: [], typebs: [], typeas: [] }, processresults: function (object, start) { return function (response) { //var marker = +new date(); // log end timestamp //var diff = marker - start; //console.log("start processing " + object.name + ": " + diff); ...cut brevity... //marker = +new date(); // log end timestamp //diff = marker - start; //console.log("finished processing " + object.name + ": " + diff); } }, getsinglesearchparams: function (object) { return { searchphrase: this.searchoptions.searchphrase, type: object.typeid, facets: object.facets }; }, getsearchresults: function (object, start) { if (object.include) datafactory.searchfactory.search(this.getsinglesearchparams(object)).success((this.processresults)(object, start)); else { var message = object.name + " not selected search"; throw message; } }, search: function () { var start = +new date(); var searches = {}; if (this.searchoptions.foos.include) { searches.fooresults = this.getsearchresults(this.searchoptions.foos, start); } if (this.searchoptions.bars.include) { searches.barresults = this.getsearchresults(this.searchoptions.bars, start); } if (this.searchoptions.typebs.include) { searches.typebresults = this.getsearchresults(this.searchoptions.typebs, start); } if (this.searchoptions.typeas.include) { searches.typearesults = this.getsearchresults(this.searchoptions.typeas, start); } $q.all(searches); } }; searchfactory's 'search' method contains $http calls:
searchfactory.search = function (searchoptions) { return $http.post(searchurl, searchoptions); }; the commented out code shows timings , revealed serial nature of processing results...
start processing typebs: 162 finished processing typebs: 164 start processing typeas: 535 finished processing typeas: 535 start processing foos: 553 finished processing foos: 554 start processing bars: 1616 finished processing bars: 1617
your http requests are running in parallel. processresults function executed after http requests have returned, why appear serial you. add log line here , see happens:
getsearchresults: function (object, start) { if (object.include) console.log("starting request object %o", object); // http request made datafactory.searchfactory.search(this.getsinglesearchparams(object)).success((this.processresults)(object, start)); else { var message = object.name + " not selected search"; throw message; } }, by way, $q.all doesn't in code. benefit of $q.all allows after guaranteeing of promises have resolved. however, you're processing each request returns.
var promises = [ $http.get('foo'), $http.get('bar') ]; // @ point, both http requests have fired, in parallel. $q.all isn't responsible this. $q.all(promises) .then(function(responses){ // if execute logic can happen after both http requests return, you'd use $q.all. }); if want process search results after searches have finished, place processing business logic inside callback $q.all.
edit: refactored code little bit uses $q.all.
var searchservice = { processresults: function(responses) { // responses array of response objects. whatever here. }, getsinglesearchparams: function(object) { return { searchphrase: this.searchoptions.searchphrase, type: object.typeid, facets: object.facets }; }, getsearchresults: function(object, start) { // no need throw error here. place call method, can guarantee called object selected search. // i've added `return` keyword, returns promise, , removed `processresults`. process reults after `$q.all`. return datafactory.searchfactory.search(this.getsinglesearchparams(object)); }, search: function() { var self = this; var start = new date(); var promises = ['foos', 'bars', 'typebs', 'typeas'].reduce(function(promises, search) { if (self.searchoptions[search].include) { promises.push(self.getsearchresults(self.searchoptions[search], start)) } return promises; }, []); return $q.all(promises) .then(this.processresults.bind(this)); } };
Comments
Post a Comment