Last active
August 8, 2018 15:12
-
-
Save djtango/d98ddbbaf4453ea6776a268058dc992f to your computer and use it in GitHub Desktop.
callback hell
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 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