Bluebirdjs promises wrapped in a for loop

I have a bunch of functions used to provide data for my service. I want to go through each of them and stop as soon as one of them returns the desired result. If the first one works, that's fine. If it has an exception or the data is invalid, I would like to move on to the next, etc.

How can i achieve this? I have the code below:

handleData: function(address) { var self = this; return new Promise(function (resolve, reject) { for (var i = 0; i < self.listAllAvailableProviders.length; ++i) { var handler = self.listAllAvailableProviders[i]; new handler().getData(address) .then(function(value) { Logger.info(value); resolve(value); }) .catch(function(err){ Logger.error(err); }) } reject(""); }); } 

how can i fix this to stop as soon as the first one gets the right data? I read the bluebirdjs documentation bluebirdjs no avail.

EDIT I put a break statement after resolve , and I got the following:

 SyntaxError: Illegal break statement at Object.exports.runInThisContext (vm.js:53:16) at Module._compile (module.js:513:28) at Object.Module._extensions..js (module.js:550:10) at Module.load (module.js:458:32) at tryModuleLoad (module.js:417:12) at Function.Module._load (module.js:409:3) at Module.require (module.js:468:17) at require (internal/module.js:20:19) 
+1
source share
2 answers

You execute all your queries in parallel in a for loop, so when you find one that has a value that you like, the others are already running, so there is no way to “not run” them. If you do not want to run the rest as soon as you find them, you do not need to run them in parallel. Thus, this will lead you to a design pattern where you will serialize queries. Run it, if it fails, run the next one, etc.

As far as I can tell, there is no built-in circuit in Bluebird to accomplish what you ask. The simplest thing I can think of is to use one of the array processing functions in Bluebird, which will serialize the queries one after another, like Promise.mapSeries() , and then use the reject to abort processing when you find a good value.

 handleData: function(address) { return Promise.mapSeries(this.listAllAvailableProviders, function(handler) { return new handler().getData(address).then(function(value) { // the first success we get, we will throw with // the returned value in order to stop the .mapSeries progression throw value; }, function(err) { // log the error, but don't let the rejection propagate so other handlers are called Logger.error(err); }) }).then(function() { // nothing succeeded here, turn it into an overall rejection throw new Error("No getData() handlers succeeded"); }, function(val) { // reject here means we got a good value so turn it into a resolved value return val; }) } // usage obj.handleData().then(function(val) { // got value here }).catch(function(err) { // no values here }); 

Curiously, this is apparently less code, and perhaps a little easier if you just iterate over the handlers yourself:

 handleData: function(address) { var index = 0; var handlers = this.listAllAvailableProviders; var handlerCnt = handlers.length; function next() { if (index < handlerCnt) { var handler = handlers[index++]; return new handler().getData(address).catch(next); } else { return Promise.reject(new Error("No handler found for address")); } } return next(); } 
+2
source

if promises is not a strict limitation caolan / asyn # eachSeries or the like may help. Sort of...

 // var Promise = require(?) // var async = require("async") handleData: asyncProviderFinder ... function asyncProviderFinder(address){ var self = this; return new Promise(function(resolve, reject){ async.eachSeries( self.listAllAvailableProviders, function iterate(provider, next){ var handler = provider; new handler().getData(address) .then( function(value){ Logger.info(value); next("abort"); // callback any error to abort future iterations return resolve(value); }) .catch( function (err){ Logger.error(err); next(); }); }, function callback(err, firstProvider){ if ((firstProvider === undefined) && !err ){ reject(""); } } ); }); } 
0
source

All Articles