Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- class FunctifiedAsync {
- constructor(iterable) {
- this.iterable = iterable;
- }
- async *[Symbol.asyncIterator]() {
- for await (const value of this.iterable) {
- yield value;
- }
- }
- map(callback) {
- const iterable = this.iterable;
- return FunctifiedAsync.fromGenerator(async function* () {
- for await (const value of iterable) {
- yield callback(value);
- }
- });
- }
- skipWhile(predicate) {
- const iterable = this.iterable;
- return FunctifiedAsync.fromGenerator(async function* () {
- let skip = true;
- for await (const value of iterable) {
- if (!predicate(value)) {
- skip = false;
- }
- if (!skip) {
- yield value;
- }
- }
- });
- }
- flatten() {
- const iterable = this.iterable;
- return FunctifiedAsync.fromGenerator(async function* () {
- for await (const value of iterable) {
- if (value[Symbol.iterator] || value[Symbol.asyncIterator]) {
- yield* new FunctifiedAsync(value);
- } else {
- yield value;
- }
- }
- });
- }
- takeUntil(predicate) {
- const iterator = this.iterable[Symbol.asyncIterator]();
- const self = this;
- return FunctifiedAsync.fromGenerator(async function* () {
- if (self.hasOwnProperty("startValue")) {
- yield self.startValue;
- }
- while (true) {
- const result = await iterator.next();
- if (result.done) {
- break;
- } else {
- if (predicate(result.value)) {
- // save the value so we can yield if takeUntil is called again
- self.startValue = result.value;
- break;
- } else {
- yield result.value;
- }
- }
- }
- });
- }
- static fromGenerator(generator) {
- return new FunctifiedAsync({
- [Symbol.asyncIterator]: generator
- });
- }
- }
- const timeoutPromise = timeout => new Promise(resolve => setTimeout(resolve, timeout))
- // This could be an async API request, but here we just mock the result
- const getItemsForPage = (number) => {
- console.log(`getting page ${number}`)
- return timeoutPromise(1000).then(() => [1, 2, 3, 4].map(x => x + (number * 4)))
- }
- const generateNumbers = function* (n = 0) {
- yield n;
- const next = n + 1;
- // Recurse and delegate to the next generator
- yield* generateNumbers(next)
- }
- async function main() {
- // Paginate until we find items 7-10.
- // Because we're using async iterators, this is lazy. So we won't make
- // any requests after we've found our last item (takeUntil).
- const asyncIterable = new FunctifiedAsync(generateNumbers())
- .map(getItemsForPage)
- .flatten()
- .skipWhile(x => x < 7)
- .takeUntil(x => x > 10)
- for await (const x of asyncIterable) {
- console.log(x)
- }
- }
- main().catch(console.error)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement