Created
December 16, 2015 15:46
-
-
Save mcsf/32c04f30fe7dbc933839 to your computer and use it in GitHub Desktop.
Silly experiments with loops and async
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| //// 1 | |
| // We could use an immediately-invoked function named 'recur' calling itself, | |
| // but that would pollute scope. Thus, use a block and 'const'. | |
| { | |
| const recur = (foo) => | |
| setTimeout(() => { | |
| console.log('A', Date.now(), foo) | |
| recur('C') | |
| }, 250) | |
| recur() | |
| } | |
| //// 2 | |
| // A bare-bones higher-order function to deal with recursion. | |
| const recur = (fn, ...args) => fn(recur.bind(null, fn), ...args) | |
| // The following is equivalent to the previous solution. | |
| recur((next, foo) => | |
| setTimeout(() => { | |
| console.log('B', Date.now(), foo) | |
| next('C') | |
| }, 250)) | |
| // Which leads us to the idea that we can control when to stop the cycle and | |
| // what seed to pass to the next iteration. | |
| recur((next, i = 0) => { | |
| if (i >= 10) return; | |
| console.log('Got', i) | |
| next(i + 1) | |
| }) | |
| // 3 | |
| // Though for that we don't have to reinvent the wheel: enter 'unfold'. | |
| import { unfold } from 'ramda' | |
| // This is equivalent to the previous `recur` solution, though it returns a | |
| // list. | |
| unfold(i => i >= 10 ? false : [ i, i + 1 ], 0) | |
| .forEach(i => console.log('Got', i)) | |
| // This loops indefinitely. | |
| unfold(() => { | |
| console.log('Z', Date.now()) | |
| return [ 0, 0 ] | |
| }, 0) | |
| const l = console.log.bind(console, '->') | |
| // 4 | |
| // Can we conceive an async flavor of `unfold`? | |
| const unfoldAsync = (fn, initial) => new Promise(resolve => { | |
| const xs = [] | |
| const recur = (seed) => { | |
| const result = fn(seed) | |
| if (result === false) { | |
| resolve(xs) | |
| return | |
| } | |
| const [ cur, next ] = result | |
| Promise.resolve(cur).then(x => { | |
| xs.push(x) | |
| recur(next) | |
| }) | |
| } | |
| recur(initial) | |
| }) | |
| const remoteRequest = foo => new Promise(resolve => | |
| setTimeout(() => resolve(foo * 100) , 5)) | |
| unfoldAsync(i => i > 3 ? false : [ wait(i), i + 1 ] , 0) | |
| .then(l) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment