# sequencing / reducing promises
Implement a Promise sequencing API that passes the return value of each Promise to the next, like a reducer.
# reducer()
const initialValue = 1
const oneStep = () => reducer(initialValue, 2);
const twoSteps = () => reducer(oneStep(), 2);
const threeSteps = () => reducer(twoSteps(), 2);
function reducer(accumulator, nextValue) {
  return accumulator * nextValue
}
# Array#reduce()
const initialValue = 1
const oneStep = () => [2].reduce(reducer, initialValue);
const twoSteps = () => [2, 2].reduce(reducer, initialValue);
const threeSteps = () => [2, 2, 2].reduce(reducer, initialValue);
# makePromise()
const Log = msg => () => console.log(msg)
const [promise, resolve, reject] =
  makePromise()
promise
  .then(Log('then'))
  .catch(Log('catch'))
  .finally(Log('finally'))
function makePromise() {
  let resolve
  let reject
  const promise = new Promise((O, X) => {
    resolve = O
    reject = X
  })
  return [promise, resolve, reject]
}
# hold()
const pause = () =>
  hold(1).then(console.log)
function hold(n) {
  const [promise, resolve] = makePromise()
  setTimeout(
    () => resolve(`took ${n} seconds`),
    n * 1000
  )
  return promise
}
# makePromiseSequencer()
const initialValue = 1
const queue = makePromiseSequencer(
  () => initialValue
)
queue([
  acc => pause().then(() => acc * 2),
  acc => pause().then(() => acc * 2),
  acc => pause().then(() => acc * 2)
]).then(accumulated =>
  console.log(accumulated)
)
function makePromiseSequencer(
  initialValueFn
) {
  return promiseMakerFns => {
    const [promise, resolve, reject] =
      makePromise()
    promiseMakerFns
      .reduce(
        SequenceReducer(reject),
        Promise.resolve(initialValueFn()),
      )
      .then(resolve, reject);
    return promise
  }
  function SequenceReducer(reject) {
    return (
      lastPromise,
      createNextPromise
    ) =>
      lastPromise.then(
        createNextPromise,
        reject
      )
  }
}