0

I'm writing a Software that has the following flow:

Promise.resolve(updateMongoStatus)
  .then(unzipFilesFromS3)
  .then(phase4) //example
  .then(phase5) //example
  .then(processSomething)
  .catch(saveErrorToMongo)

And I would like to know if it's ok to pass data around from the first function, to the last one, for example:

function updateMongoStatus() {
  // do something here that updates Mongo and get status of some document

  return { status }
}

function unzipFilesFromS3({ status }) {
  // do something here to unzip files from s3
  return { status, files }
}

function phase4({ status, files }) {
  // etc
}

Until the processSomething finally gets called:

function processSomething({ parameterFromOutputOfUpdateMongoStatus, parameterFromPhase4, parameterFromPhase5 }) {
  // Do something here
}

Is this ok? To pass data around like that?

Thank you.

Amanda Ferrari
  • 1,168
  • 5
  • 17
  • 30
  • Yes, this is totally ok, although there may be [simpler solutions to do that](https://stackoverflow.com/q/28250680/1048572). – Bergi Mar 14 '18 at 05:39
  • WOW, that's perfect Bergi! OHMG <3 – Amanda Ferrari Mar 14 '18 at 05:44
  • just a hint, `Promise.resolve(updateMongoStatus)` won't return a `Promise<{ status }>` but a `Promise`. You probably mean `Promise.resolve().then(updateMongoStatus)` – Thomas Mar 14 '18 at 06:25

2 Answers2

3

Yes! This is totally ok, and for some people, this is the preferred way to pass data through a Promise chain (because it does not involve any globals / variables outside the scope of the Promise blocks).

In your case, since you want phase4, phase5, and mongo status in your last promise, you could do this:

Promise
  .resolve(mongoStatus)
  .then((mongoResult) => { 
    return unzipFilesFromS3().then(s3Result => {
      return [s3Result, mongoResult];
    });
})
.then(([ s3Result, mongoResult ]) => {

  return Promise.all([
    mongoResult, 
    s3Result,
    phase4(mongoResult, s3Result) 
  ]);
}) 
// repeat with phase5
.then(([ mongoResult, s3Result, phase4Result /* phase5, etc */ ]) => {
  // etc
})
.catch(err => {});
aidan
  • 1,627
  • 17
  • 27
-1

No, you will need to pass a promise object from a thenable to the next thenable. If you simply pass a value, it will return the value.

When a value is simply returned from within a then handler, it will effectively return Promise.resolve().

Promise.prototype.then()

Update as of 14/03/2018: This answer is not correct. Please refer to comment from @Bergi

codemax
  • 1,322
  • 10
  • 19
  • 1
    You're contradicting yourself. First you say that one needs to return a promise, but then you say that returning a value also works? – Bergi Mar 14 '18 at 05:43
  • Maybe my understanding of chaining promises is wrong then. But what's the purpose of chaining multiple thenables if you are not passing a promise to the next thenable? – codemax Mar 14 '18 at 05:45
  • Usually, simplicity. Of course multiple synchronous callbacks chained onto each other could be merged into a single callback, but if the functions already exist as building blocks you might just call `then` multiple times. Example `.then(JSON.parse).then(printData)` is simpler than `.then(function(result) { return printData(JSON.parse(result)); })` – Bergi Mar 14 '18 at 05:55