Skip to content

Instantly share code, notes, and snippets.

@djtango
Last active August 8, 2018 15:12
Show Gist options
  • Save djtango/d98ddbbaf4453ea6776a268058dc992f to your computer and use it in GitHub Desktop.
Save djtango/d98ddbbaf4453ea6776a268058dc992f to your computer and use it in GitHub Desktop.
callback hell
const genLongString = (url) => {
// doesn't actually use the url
let chars = [];
const bigNum = Math.floor(Math.random() * 1000000 + 1000000);
for (let i = 0; i <= bigNum; i += 1) { chars.push('x'); }
const longString = chars.join('');
return longString;
};
const getLargeExternalData = (url, retn) => {
setTimeout(() => {
console.log('fetching data from ' + url + '...');
const longString = genLongString(url);
retn(longString);
} , 1000);
};
const getSize = (data, retn) => {
setTimeout(() => {
console.log('calculating size of data...');
retn(data.length);
}, 1000);
};
const intoMBs = (size, retn) => {
setTimeout(() => {
const sizeInMBs = size / 1024;
retn(sizeInMBs);
}, 1000);
};
const postResult = (sizeInMBs) => {
setTimeout(() => { console.log('posting result: ' + sizeInMBs + 'MBs')}, 1000);
};
//callback hell style...
getLargeExternalData('wat.js', (data) => {
getSize(data, (size) => {
intoMBs(size, (sizeInMBs) => {
postResult(sizeInMBs);
});
});
});
// promises style
const promisify = (f) => (arg) => {
return new Promise(function(resolve, reject) {
f(arg, resolve)
});
};
const getLargeExternalDataP = promisify(getLargeExternalData);
const getSizeP = promisify(getSize);
const intoMBsP = promisify(intoMBs);
const postResultP = promisify(postResult);
getLargeExternalDataP('wat.promise')
.then((data) => getSizeP(data))
.then((size) => intoMBsP(size))
.then((sizeInMBs) => postResultP(sizeInMBs));
// async await
async function doAsync() {
const data = await getLargeExternalDataP();
const size = await getSizeP(data);
const sizeInMBs = await intoMBsP(size);
await postResultP(sizeInMBs);
}
doAsync();
// CPS
const doCPS = (firstArg, fs) => {
const iter = (arg, gs) => {
const [g, ...rest] = gs;
if (gs.length > 0) {
return g(arg, (returnedValue) => iter(returnedValue, rest));
} else {
return g(arg, (finalValue) => console.log(finalValue));
}
}
return iter(firstArg, fs);
};
doCPS('wat.cps', [
getLargeExternalData,
getSize,
intoMBs,
postResult,
]);
// BONUS LEVEL:
// the function signatures suck for these CPS functions!
// let's rewrite the code to have a more typical signature:
const _getLargeExternalData = (url) => {
console.log('fetching data from ' + url + '...');
const longString = genLongString(url);
return longString;
};
const _getSize = (data) => {
console.log('calculating size of data...');
return(data.length);
};
const _intoMBs = (size) => {
const MBs = 1024;
return(size / MBs);
};
// convert into delayed and async functions
const addDelay = (f) => (...args) => { setTimeout(() => f.apply(null, args), 1000); };
const liftAsync = (f) => (arg, retn) => { retn(f(arg)); };
const delayWithAsync = (f) => addDelay(liftAsync(f));
const getLargeExternalData2 = delayWithAsync(_getLargeExternalData);
const getSize2 = delayWithAsync(_getSize);
const intoMBs2 = delayWithAsync(_intoMBs);
doCPS('wat2.cps', [
getLargeExternalData2,
getSize2,
intoMBs2,
postResult
]);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment