Skip to content

Instantly share code, notes, and snippets.

View dtipson's full-sized avatar

Drew dtipson

View GitHub Profile
dtipson / complete-pipeline-two.js
Last active December 26, 2023 15:08
An even simpler pipeline
const outputs = await pipe(
postIds,// array of numbers, which is... already an iterable
mapGen(fetchById),// generator of an array of eventually all resolved promises (requested in chunks of 3)
chunkGen(5),// generator of arrays of 5 promises, our "batch"
spreadBatchesAsyncGen,// async generator of individual resolved promises
forEachAsyncGen(renderPost)// Promise of an array of numbers
dtipson / spreadBatchesAsyncGen.js
Last active January 5, 2024 16:00
Spreading out a generator of arrays into a generator of items
// spreadBatchesAsyncGen :: Iterator[[...Promises]] -> AsyncGenerator[[...Promises]]
const spreadBatchesAsyncGen = async function* (iterableOfPromises) {
for (let array of iterableOfPromises) {
yield* await Promise.all(array)
dtipson / complete-pipeline.js
Last active December 26, 2023 03:59
A pipeline version
await pipe(
postIds[Symbol.iterator](),// creates a generator from a plain array of postIds
chunkGen(5),// generator that pulls in 5 numbers and yields them out in arrays of 5
mapGen(map(fetchById)),// generator that takes in arrays of numbers & turns them into arrays of requests
spreadBatchesAsyncGen,// async generator that spreads arrays of resolved promises & emits one promise at a time
forEachAsyncGen(renderPost)// a function that consumes the generator & does something with each result
dtipson / batchTasks-spread.js
Last active December 25, 2023 19:42
Revised batchTasks generator
export async function* batchTasks(tasks = [], limit = 5, taskCallback = r => r) {
for (let i = 0; i < tasks.length; i = i + limit) {
const batch = tasks.slice(i, i + limit)
yield* await Promise.all( => task().then(taskCallback))
dtipson / send-postMessage-events.js
Created September 25, 2018 19:45
Sending postMessage events
function throttle(fn, threshhold = 250, scope) {
var last,
return function () {
var context = scope || this;
var now = +new Date,
args = arguments;
if (last && now < last + threshhold) {
// hold on to it
dtipson / quick-stream-self.js
Last active July 26, 2017 19:44
Can run in console on any https site on Chrome/Firefox
document.body.innerHTML = '';
const delay = milliseconds => x => new Promise(resolve => setTimeout(resolve, milliseconds, x));
//requestRecord :: Object (optional) -> Promise Stream
const requestRecord = (config={video:true, audio:true}) => {
return navigator.mediaDevices && navigator.mediaDevices.getUserMedia ?
navigator.mediaDevices.getUserMedia(config).then(delay(1400)) : // delay avoid startup flash
Promise.reject('no support for getUserMedia');
// mapping over an array with an async function
// would return an Array of Promises which isn't
// super useful to work with on its own
async function fooPromise(x){
return Promise.resolve(x*3);
const arr = [6,7,8,9];// -> [Promise[18],Promise[21],Promise[24],Promise[27]]]
dtipson / KeyedCollection.js
Created April 24, 2017 20:58
Experimenting with a type that contains objects that are listed in insertion order but are also unique by a single chosen prop
const getProp = prop => object => object[prop]
function KeyedCollection (Iterable, prop){
if (!(this instanceof KeyedCollection)) {
return new KeyedCollection(Iterable, prop);
throw new Error('must supply a prop')
const it_target = []
const selectPropFrom = getProp(prop)
// Finally wrapped your head around Promises? Time to toss out all that knowledge and learn the functional alternative!
// Here's a super simple implementation of a Task "type"
const __Task = fork => ({fork})
// Absurdly simple! All we're doing is using a function that returns some unknown value, by name, in an object.
// At this point "fork" is just a cute name though: what matters is how we use it.
// What makes Task a "Task" is that is that the "fork" value here... will be a higher-order function.
// Here's a usage example, already fully functional, already nearly as powerful as Promise!
var object = {
increment(){ return ++this.value; }
But of course, even though that value is central to what the object is,
it's not really a _primitive_ value in the sense that we can directly coerce it into a number or string: