Skip to content

Instantly share code, notes, and snippets.

@franciscotln
Created December 19, 2018 22:21
Show Gist options
  • Save franciscotln/695bba17d3aa19eab6d7b5391409850c to your computer and use it in GitHub Desktop.
Save franciscotln/695bba17d3aa19eab6d7b5391409850c to your computer and use it in GitHub Desktop.
const pipe = (...fns) => {
let [res] = fns;
for (let i = 1, n = fns.length; i < n; i++) res = fns[i](res);
return res;
};
const concat = iter2 => async function* (iter1) {
yield* await iter1;
yield* await iter2;
};
const take = n => async function* (iter) {
let i = 0;
for await (let v of iter) {
if (++i < n) {
yield v;
} else {
yield v;
break;
}
}
};
async function* range(from, to, step = 1) {
let i = from;
while (i !== to) {
yield i;
i += step;
}
}
function fromEvent(target, eventName) {
let resolve;
function setResolve(res) {
resolve = res;
}
function listener(event) {
resolve({ done: false, value: event });
}
return {
[Symbol.asyncIterator]() {
target.addEventListener(eventName, listener);
return {
next() {
return new Promise(setResolve);
},
return() {
target.removeEventListener(eventName, listener);
return Promise.resolve({});
}
};
}
};
}
const subscribe = (observer = {}) => iter => {
let terminate = false;
(async () => {
try {
for await (let v of iter) {
if (terminate) break;
observer.next && observer.next(v);
}
!terminate && observer.complete && observer.complete();
} catch (err) {
!terminate && observer.error && observer.error(err);
}
})();
return {
unsubscribe() {
terminate = true;
}
}
};
const subscription = pipe(
fromEvent(document, 'click'),
take(4),
concat(range(0, 5)),
subscribe({
next(val) {
console.log(val);
},
complete() {
console.log('done!');
},
error(err) {
console.log(err);
}
})
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment