Sylwek
Sylwek

Reputation: 866

Chaining promises one by one till one return not empty result

I have a specific problem with promises - I didn't find any solution for my problem.

I have list of services(classes), for example

const services = [
     FirstCacheDataProvider,
     SecondCacheDataProvider,
     // etc, there can be more services, unspecified number of services
];

Each class implements methods (for example find) which returns promise(it's resolved inside this method and I don't have access to body of this method. It's obviously asynchronous)

Now I want to call this methods one by one till one return NOT EMPTY result.

Is there any way to do this without big chain of then?

Example of workflow:

We have 4 services

FirstCacheDataProvider.find() // result of promise is empty
SecondCacheDataProvider.find() // result of promise is empty
ThirdCacheDataProvider.find() // result of promise IS NOT EMPTY
// fourth service's method is not called

Upvotes: 0

Views: 78

Answers (2)

Yury Tarabanko
Yury Tarabanko

Reputation: 45121

Something like this should do the trick. I assumed by NOT EMPTY you meant other than undefined :)

const services = [
  FirstCacheDataProvider,
  SecondCacheDataProvider,
  // etc, there can be more services, unspecified number of services
]

// reduce all services to a promise that either returns first value or calls next service.find
services.reduce(
  (pending, service) => pending.then(value => value !== undefined ? value : service.find()),
  Promise.resolve()
).then(firstNonEmptyResult => console.log(firstNonEmptyResult))

Upvotes: 1

CertainPerformance
CertainPerformance

Reputation: 370679

A simple method would be to use a for loop and await each service call in an async function:

for (let i = 0; i < services.length; i++) {
  const result = await services[i].find();
  if (result === 'NOT EMPTY') { // or whatever condition you're searching for.. .length?
    break;
  }
}

Upvotes: 6

Related Questions