Asynchronous Code and Callback Functions
- Synchronous code always runs before asynchronous code.
For example the console log runs before the setTimeout
function (which is async)
setTimeout(() => [
console.log('Inside timeout')
])
console.log('hello')
// hello
// Inside timeout
Promises
- Promises is another way to represent asynchronous code
- A promise is an object with 3 states:
pending
,resolved
andrejected
.
The following promise:
const myPromise = new Promise((resolve, reject) => {
resolve("hello")
})
console.log(myPromise);
// Promise { 'hello' }
As we can see, we get a pending object
.
In order to get the actual value
we need to resolve it.
const myPromise = new Promise((resolve, reject) => {
resolve("hello")
})
myPromise.then((val) => {
console.log(val);
})
// hello
Instead of getting an object with pending state, we get the resolved promise.
We can chain .then
infinitely:
const myPromise = new Promise((resolve, reject) => {
resolve("hello")
})
myPromise.then((val) => {
console.log(val);
return 10;
}).then((newVal) => {
console.log(newVal)
})
// 10
If we reject the promise, we can catch the error thrown:
const myPromise = new Promise((resolve, reject) => {
reject("error!")
})
myPromise.then((val) => {
console.log(val);
}).catch((err) => {
console.log(err);
})
// error!
A better example with setTimeout()
:
const myPromise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("Hello after 1 second")
}, 1000)
})
myPromise.then((val) => {
console.log(val);
}).catch((err) => {
console.log(err);
})
// Hello after 1 second <== after 1 second
But we can have the promise inside a function:
const myPromiseFunc = (num) => {
return new Promise((resolve, reject) => {
if (num > 5) {
resolve('number is > 5')
} else {
reject('number is < 5')
}
})
}
myPromise(10).then((val) => {
console.log(val);
}).catch((err) => {
console.log(err);
})
// number if > 5
If we trigger the reject
instead:
const myPromiseFunc = (num) => {
return new Promise((resolve, reject) => {
if (num > 5) {
resolve('number is > 5')
} else {
reject('number is < 5')
}
})
}
myPromise(3).then((val) => {
console.log(val);
}).catch((err) => {
console.log(err);
})
// ERROR: number if < 5
Using Async/Await
const myPromiseFunc = (num) => {
return new Promise((resolve, reject) => {
if (num > 5) {
resolve('number is > 5')
} else {
reject('number is < 5')
}
})
}
async function executeMyPromise() {
try {
const val = await myPromiseFunc(10)
console.log(val)
} catch (error) {
console.log('ERROR:', error)
}
}
Dealing with multiple promises
const myPromiseFunc = (num) => {
return new Promise((resolve, reject) => {
if (num > 5) {
resolve('number is > 5')
} else {
reject('number is < 5')
}
})
}
async function executeMyPromise() {
try {
const val = await fetch1()
const otherVal = await fetch2(val) // here the second depends on the value from the first promise
console.log(val)
} catch (error) {
console.log('ERROR:', error)
}
}
But if they can be handled in parallel (they are independent from each other):
const myPromiseFunc = (num) => {
return new Promise((resolve, reject) => {
if (num > 5) {
resolve('number is > 5')
} else {
reject('number is < 5')
}
})
}
async function executeMyPromise() {
try {
const promises = [fetch1(), fetch2()]
const result = await Promise.all(promises);
// result will be an array of resolved values. If one promise fails, all fail.
// Or as well:
const [ val1, val2 ] = await Promise.all(promises);
} catch (error) {
console.log('ERROR:', error)
}
}
Backlinks
Javascript
- [[javascript-async-callback]]