Last active
March 21, 2020 19:46
-
-
Save zaceno/a5fff27744cf2f430d8d92f08e1bd9e8 to your computer and use it in GitHub Desktop.
chain nested setTimeout calls
This file contains hidden or 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
/* | |
If you ever end up writing deep sideways pyramids of | |
setTimeouts, you can use this utility to sequentialize | |
them. | |
step(a).step(b).step(c) | |
is equivalent to | |
setTimeout(() => { | |
let x = a() | |
setTimeout(() => { | |
let y = b(x) | |
setTimeout(() => { | |
c(y) | |
}, 0) | |
}, 0) | |
}, 0) | |
*/ | |
const step = ((w=(f,n,g=x=>setTimeout((y=f(x))=>n&&n(y),0))=>((g.step=f=>((n=w(f)),n)),g))=>(f,s=w(f))=>(s(),s))() | |
export default step | |
/* | |
I made the code compact like that, so it wouldn't be a bother to just | |
copy and paste wherever I need it. It doesn't need to be readable, | |
because I don't need to change it. But in case anyone is | |
curious, here's how it unrolls into more readable code: | |
const makeStep = stepFunc => { | |
// memory for step chained after this one | |
let chained = null | |
// wraps the stepFunc in a setTimeout | |
let wrapped = prevStepReturnValue => | |
setTimeout(() => { | |
//execute the function after timeout | |
let valueForNextStep = stepFunc(prevStepReturnValue) | |
//in case a chained step is defined, execute it | |
//it will set a new timeout | |
if (chained) chained(valueForNextStep) | |
}, 0) | |
//make the wrapped function chainable | |
wrapped.step = stepFunc => { | |
//wrap next step and remember | |
//that it is chained to this one | |
chained = makeStep(stepFunc) | |
//return it so that furthe steps | |
//can be chained to it. | |
return chained | |
} | |
return wrapped | |
} | |
const step = firstStep => { | |
//wrap the function in a chainable timeout. | |
let wrappedFirstStep = makeStep(firstStep) | |
//start the chain. | |
wrappedFirstStep() | |
// Don't worry, it doesn't execute | |
//anything until after a timeout, so there's time | |
//to chain other steps on to this. | |
//return so we can chain .step | |
return wrappedFirstStep | |
} | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment