Created
January 29, 2018 19:36
-
-
Save mariusGundersen/67f40b2a33f79aa4594d5a6ab0f02bfd to your computer and use it in GitHub Desktop.
(Async) Iterator pipe
This file contains 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
const result = pipe([1, 2, 3]) | |
.pipe(through) | |
.pipe(i => some('steps', i)) | |
.pipe(toAsync) | |
.pipe(delayed(100)) | |
.then(concat) | |
function* through(iterator){ | |
for(const item of iterator){ | |
yield* new Array(item).fill(item); | |
} | |
} | |
function* some(prefix, iterator){ | |
for(const item of iterator){ | |
yield `${prefix}-${item}`; | |
} | |
} | |
async function* toAsync(iterator){ | |
for(const item of iterator){ | |
yield item; | |
} | |
} | |
const delayed = (time) => async function*(iterator){ | |
for await(const item of iterator){ | |
await Promise.delay(time); | |
yield item; | |
} | |
}; | |
async function concat(iterator){ | |
let result = ''; | |
for await(const item of iterator){ | |
result += item; | |
} | |
return result; | |
} | |
Promise.delay = function(time, value){ | |
return new Promise(res => setTimeout(() => res(value), time)); | |
} |
This file contains 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
export default function pipe(input) { | |
if (isPipable(input)) { | |
return input; | |
} | |
if (isAsync(input)) { | |
return { | |
[Symbol.asyncIterator]() { | |
return input[Symbol.asyncIterator](); | |
}, | |
next(value) { | |
return input.next(value); | |
}, | |
return: input.return ? (value) => input.return(value) : undefined, | |
throw: input.throw ? (e) => input.throw(e) : undefined, | |
pipe(next) { | |
return pipe(next(input)); | |
}, | |
then(func) { | |
return func(input); | |
} | |
}; | |
} | |
if (isIterator(input)) { | |
return { | |
[Symbol.iterator]() { | |
return input[Symbol.iterator](); | |
}, | |
next(value) { | |
return input.next(value); | |
}, | |
return: input.return ? (value) => input.return(value) : undefined, | |
throw: input.throw ? (e) => input.throw(e) : undefined, | |
pipe(next) { | |
return pipe(next(input)); | |
}, | |
map(func) { | |
return func(input); | |
} | |
}; | |
} | |
return pipe(toIterableIterator(input)); | |
} | |
function* toIterableIterator(items) { | |
yield* items; | |
} | |
function isPipable(input) { | |
return 'pipe' in input; | |
} | |
function isAsync(input) { | |
return Symbol.asyncIterator in input; | |
} | |
function isIterator(input) { | |
return 'next' in input; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment