1

I'm trying to do this:

service.getConfig()
.then(cfg => service.getData())
.then(data => service.process(data,cfg))
.then(results => console.log(results))
.catch(err => console.log(err));

The obvious problem here is that cfg goes out of scope in the second .then block. There are many messy ways I can fix this, like by declaring cfg in an outer scope, or passing cfg through service.getData() some how and returning [data,cfg]. But is there a nice way to code this without loosing the beautiful concise elegance of chained promises and one-line arrow functions?

BG100
  • 4,481
  • 2
  • 37
  • 64
  • Does this answer your question? [How do I access previous promise results in a .then() chain?](https://stackoverflow.com/questions/28250680/how-do-i-access-previous-promise-results-in-a-then-chain) – FZs Dec 01 '20 at 14:23

3 Answers3

1

Asumming you don't actually need to run service.getConfig() before service.getData() (since service.getData() doesn't receive any parameters). You could use Promise.all to run both tasks in parallel like this:

Promise.all([service.getConfig(), service.getData()])
  .then(([cfg, data]) => service.process(data, cfg))
  .then((results) => console.log(results))
  .catch((err) => console.log(err));
1

As you've said for this example as the order of calls doesn't matter running them in parallel is the way to go.

But just out of interest, if call order did matter, the way to pass data and cfg through the chain using only 'native' promises (and not having to change the implementation of service.getData() to pass through cfg, as you said) would be to use an inner then, like so:

service.getConfig()
  .then(cfg => service.getData().then(data => ({ data, cfg })))
  .then(({ data, cfg }) => service.process(data, cfg))
  .then(results => console.log(results))
  .catch(err => console.log(err));
davnicwil
  • 28,487
  • 16
  • 107
  • 123
0

Use async / await and then the arrow functions become expressions and the variables remain in scope.

async function someFunction() {
    try {
        const cfg = await service.getConfig();
        const data = await service.getData();
        const results = await service.process(data, cfg);
        return results;
    } catch (err) {
        console.log(err);
    }
}

This is ES8 rather than ES6 though.

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • Ah sorry, you're right, I meant to put ES2017, not ES6. I updated the question. Thanks for your answer though... I would be interested to see if there are any other ways to do it. – BG100 Jul 04 '20 at 22:57