|
| 1 | +// Native |
| 2 | +const fs = require('fs') |
| 3 | + |
| 4 | +// Packages |
| 5 | +const { List } = require('immutable-ext') |
| 6 | + |
| 7 | +// https://github.com/briancavalier/creed |
| 8 | +// runNode converts Node API with errback into creed promise |
| 9 | +const { runNode, Promise: CreedPromise } = require('creed') |
| 10 | + |
| 11 | + |
| 12 | +// readFilePromise :: String -> String -> Promise Error Buffer |
| 13 | +const readFilePromise = (fileName, encoding = 'utf-8') => |
| 14 | + runNode(fs.readFile, fileName, {encoding}) |
| 15 | + |
| 16 | +// wrap into List that provides 'traverse' |
| 17 | +const files = List(['file1.txt', 'file2.txt']) |
| 18 | + |
| 19 | +console.log( |
| 20 | + `Running... |
| 21 | + List(['file1.txt', 'file2.txt']) |
| 22 | + .traverse( CreedPromise.of, readFilePromise ) |
| 23 | + .then( console.log, console.error ) : |
| 24 | + ` |
| 25 | +) |
| 26 | + |
| 27 | +/* |
| 28 | + 'files' is List of files 'List(a)' |
| 29 | + 'map' preserves the List wrapper, so we can get 'List(Promise(a))' |
| 30 | + 'traverse' applies the function (a -> f b) to each List entry, |
| 31 | + then lifts the List to Promise of Lists via CreedPromise's 'ap' operator |
| 32 | + running Promises in parallel! |
| 33 | +*/ |
| 34 | + |
| 35 | +files |
| 36 | + .traverse( |
| 37 | + |
| 38 | + // type hint, applicative functor |
| 39 | + // needed in case of failure or never running the function |
| 40 | + CreedPromise.of, |
| 41 | + |
| 42 | + // traversing function a -> f b |
| 43 | + file => readFilePromise(file) |
| 44 | + ) |
| 45 | + .then( console.log, console.error ) |
0 commit comments