简体   繁体   中英

Using Promise.all inside a Ramda pipe

How is Promise.all used in a ramda pipe? I think I'm missing something silly here.

const pipeline: Function = R.pipe(
    R.map((record) => record.body),
    R.map(JSON.parse),
    R.map(asyncFunction),
    console.log
);

Returns an array of promises (the input to Promise.all )

[ Promise { <pending> },
  Promise { <pending> },
  Promise { <pending> },
  Promise { <pending> },
  Promise { <pending> },
  Promise { <pending> },
  Promise { <pending> },
  Promise { <pending> },
  Promise { <pending> },
  Promise { <pending> } ]

However if I try to wait for those promises to resolve with Promise.all , like so:

const pipeline: Function = R.pipe(
    R.map((record) => record.body),
    R.map(JSON.parse),
    R.map(asyncFunction),
    Promise.all,
    R.andThen(useTheReturn)
);

I end up with a type error stating that i'm trying to use Promise.all as a constructor type.

{
    "errorType": "TypeError",
    "errorMessage": "#<Object> is not a constructor",
    "stack": [
        "TypeError: #<Object> is not a constructor",
        "    at all (<anonymous>)",
        "    at /var/task/node_modules/ramda/src/internal/_pipe.js:3:14",
        "    at /var/task/node_modules/ramda/src/internal/_arity.js:11:19",
        "    at Runtime.exports.handler (/var/task/lambda/data-pipeline/1-call-summary-ingestion/index.js:14:19)",
        "    at Runtime.handleOnce (/var/runtime/Runtime.js:66:25)"
    ]
}

You'll need to bind Promise.all to Promise :

const pipeline: Function = R.pipe(
  R.map((record) => record.body),
  R.map(JSON.parse),
  R.map(asyncFunction),
  R.bind(Promise.all, Promise),
  R.andThen(useTheReturn)
);

Demo:

 const pipeline = R.pipe( R.bind(Promise.all, Promise), R.andThen(R.sum) ); const promise1 = Promise.resolve(10) const promise2 = 20 const promise3 = new Promise((resolve) => setTimeout(resolve, 100, 30)) const result = pipeline([promise1, promise2, promise3]) result.then(console.log)
 <script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.0/ramda.js"></script>

I have written a library called rubico , which makes this simpler because you don't need to worry about binding Promise nor using Promise.all yourself.

import { pipe, map } from 'rubico'

const pipeline: Function = pipe([
  map((record) => record.body),
  map(JSON.parse),
  map(asyncFunction),
  console.log,
]);

pipe is similar to ramda's pipe in that it chains functions together, but in the case of async functions, it will resolve the returned promise before passing the value on to the next function.

map is like ramda's map, but it just works with async functions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM