Created
December 28, 2024 23:19
-
-
Save JustinBeckwith/dec2c2c7be356609be246e7c34148150 to your computer and use it in GitHub Desktop.
Promises and JavaScript
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
// I found myself explaining this today, and figured it may be good to post something here for future reference. Enjoy! | |
/** | |
* Using callbacks | |
* | |
* Callbacks are a fancy way of saying that we pass functions around | |
* as arguments to other functions. In this case, we expect doStuff to | |
* take a really long time (a second!). When the second is over, we | |
* invoke the callback function. | |
*/ | |
function doStuff(callback) { | |
// imagine this takes a very long time | |
setTimeout(() => { | |
// after a second, invoke the callback function that was passed to us | |
callback(); | |
}, 1000); | |
} | |
console.log('start...'); | |
// we pass a function to doStuff that will be called when done | |
doStuff(() => { | |
console.log('done'); | |
// After calling it once, we may choose to call doStuff a second time | |
doStuff(() => { | |
console.log('done again'); | |
// As you can see... this works, but it gets unwieldy quickly | |
doStuff(() => { | |
console.log('done again again'); | |
}); | |
}); | |
}); | |
/** | |
* Using promises | |
* | |
* Promises are a way to handle asynchronous code in a more readable way. | |
* A promise is an object that represents the eventual completion (or failure) | |
* We can return promises, and then call `.then` or `.catch` on them. | |
*/ | |
function doStuff() { | |
return new Promise((resolve, reject) => { | |
// imagine this takes a very long time | |
setTimeout(() => { | |
// after the second is up, call `resolve`. This is very similar | |
// to the callback function in the previous example | |
resolve(); | |
}, 1000); | |
}); | |
} | |
// Notice that the promise is an actual object! We can log it, | |
// or call functions on it. | |
const p = doStuff(); | |
console.log(p); | |
console.log('start...'); | |
// The `then` method is called after `doStuff` is finished | |
p | |
.then(() => { | |
console.log('done'); | |
return doStuff(); | |
}) | |
.then(() => { | |
// In this example, chaining is a little better that the nested callback example | |
console.log('done again'); | |
return doStuff(); | |
}) | |
.catch((e) => { | |
console.error(e); | |
}); | |
/** | |
* Using async/await | |
* | |
* While promises were a nice improvement over callbacks, they're still | |
* not quite as easy to use as we'd like. That's where async and await come in! | |
* These are what we call "syntatic sugar" - they just make dealing | |
* with promises a little easier. | |
*/ | |
// instead of creating a new promise object and returning it, we can | |
// declare our function as "async" - promise creation is done for us | |
async function doStuff() { | |
await new Promise((resolve, reject) => { | |
// imagine this takes a very long time | |
setTimeout(() => { | |
resolve(); | |
}, 1000); | |
}); | |
} | |
console.log('start...'); | |
// The doStuff function actually still returns a promise! | |
const p = doStuff(); | |
console.log(p); | |
// Instead of calling .then on our promise, we can just `await` it. | |
await p; | |
console.log('done'); | |
// Chaining is easiest here, because we just keep calling `await` | |
await doStuff(); | |
console.log('done again'); | |
await doStuff(); | |
console.log('done again again'); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment