1564711349
Originally published by Mostafa Gaafar at hackernoon.com
For those who have never heard of this topic before, here’s a quick intro
Assuming a function getJSON
that returns a promise, and that promise resolves with some JSON object. We just want to call it and log that JSON, then return "done"
.
This is how you would implement it using promises
const makeRequest = () => getJSON() .then(data => { console.log(data) return "done" })makeRequest()
And this is how it looks with async/await
const makeRequest = async () => {
console.log(await getJSON())
return “done”
}makeRequest()
There are a few differences here
async
before it. The await
keyword can only be used inside functions defined with async
. Any async
function returns a promise implicitly, and the resolve value of the promise will be whatever you return
from the function (which is the string “done”
in our case).await
at the top level of our code since that is not inside an async
function.// this will not work in top level
// await makeRequest()// this will work
makeRequest().then((result) => {
// do something
})
3. await getJSON() means that the console.log
call will wait until getJSON()
promise resolves and print its value.
1. Concise and clean
Look at how much code we didn’t write! Even in the contrived example above, it’s clear we saved a decent amount of code. We didn’t have to write .then
, create an anonymous function to handle the response, or give a name data
to a variable that we don’t need to use. We also avoided nesting our code. These small advantages add up quickly, which will become more obvious in the following code examples.
2. Error handling
Async/await makes it finally possible to handle both synchronous and asynchronous errors with the same construct, good old try/catch
. In the example below with promises, the try/catch
will not handle if JSON.parse
fails because it’s happening inside a promise. We need to call .catch
on the promise and duplicate our error handling code, which will (hopefully) be more sophisticated than console.log
in your production-ready code.
const makeRequest = () => {
try {
getJSON()
.then(result => {
// this parse may fail
const data = JSON.parse(result)
console.log(data)
})
// uncomment this block to handle asynchronous errors
// .catch((err) => {
// console.log(err)
// })
} catch (err) {
console.log(err)
}
}
Now look at the same code with async/await. The catch
block now will handle parsing errors.
const makeRequest = async () => {
try {
// this parse may fail
const data = JSON.parse(await getJSON())
console.log(data)
} catch (err) {
console.log(err)
}
}
3. Conditionals
Imagine something like the code below which fetches some data and decides whether it should return that or get more details based on some value in the data.
const makeRequest = () => {
return getJSON()
.then(data => {
if (data.needsAnotherRequest) {
return makeAnotherRequest(data)
.then(moreData => {
console.log(moreData)
return moreData
})
} else {
console.log(data)
return data
}
})
}
Just looking at this gives you a headache. It’s easy to get lost in all that nesting (6 levels), braces, and return statements that are only needed to propagate the final result up to the main promise.
This example becomes way more readable when rewritten with async/await.
const makeRequest = async () => {
const data = await getJSON()
if (data.needsAnotherRequest) {
const moreData = await makeAnotherRequest(data);
console.log(moreData)
return moreData
} else {
console.log(data)
return data
}
}
4. Intermediate values
You have probably found yourself in a situation where you call a promise1
and then use what it returns to call promise2
, then use the results of both promises to call a promise3
. Your code most likely looked like this
const makeRequest = () => {
return promise1()
.then(value1 => {
// do something
return promise2(value1)
.then(value2 => {
// do something
return promise3(value1, value2)
})
})
}
If promise3
didn’t require value1
it would be easy to flatten the promise nesting a bit. If you are the kind of person who couldn’t live with this, you could wrap both values 1 & 2 in a Promise.all
and avoid deeper nesting, like this
const makeRequest = () => {
return promise1()
.then(value1 => {
// do something
return Promise.all([value1, promise2(value1)])
})
.then(([value1, value2]) => {
// do something
return promise3(value1, value2)
})
}
This approach sacrifices semantics for the sake of readability. There is no reason for value1
& value2
to belong in an array together, except to avoid nesting promises.
This same logic becomes ridiculously simple and intuitive with async/await. It makes you wonder about all the things you could have done in the time that you spent struggling to make promises look less hideous.
const makeRequest = async () => {
const value1 = await promise1()
const value2 = await promise2(value1)
return promise3(value1, value2)
}
5. Error stacks
Imagine a piece of code that calls multiple promises in a chain, and somewhere down the chain, an error is thrown.
const makeRequest = () => {
return callAPromise()
.then(() => callAPromise())
.then(() => callAPromise())
.then(() => callAPromise())
.then(() => callAPromise())
.then(() => {
throw new Error(“oops”);
})
}makeRequest()
.catch(err => {
console.log(err);
// output
// Error: oops at callAPromise.then.then.then.then.then (index.js:8:13)
})
The error stack returned from a promise chain gives no clue of where the error happened. Even worse, it’s misleading; the only function name it contains is callAPromise
which is totally innocent of this error (the file and line number are still useful though).
However, the error stack from async/await points to the function that contains the error
const makeRequest = async () => {
await callAPromise()
await callAPromise()
await callAPromise()
await callAPromise()
await callAPromise()
throw new Error(“oops”);
}makeRequest()
.catch(err => {
console.log(err);
// output
// Error: oops at makeRequest (index.js:7:9)
})
makeRequest
is better than knowing that the error came from a then
after a then
after a then
…Debugging
6. A killer advantage when using async/await is that it’s much easier to debug. Debugging promises has always been such a pain for 2 reasons
Try setting a breakpoint anywhere here
2. If you set a breakpoint inside a .then
block and use debug shortcuts like step-over, the debugger will not move to the following .then
because it only “steps” through synchronous code.
With async/await you don’t need arrow functions as much, and you can step through await calls exactly as if they were normal synchronous calls.
7. You can await
anything
Last but not least, await
can be used for both synchronous and asynchronous expressions. For example, you can write await 5
, which is equivalent to Promise.resolve(5)
. This might not seem very useful at first, but it’s actually a great advantage when writing a library or a utility function where you don’t know whether the input will be sync or async.
Imagine you want to record the time taken to execute some API calls in your application, and you decide to create a generic function for this purpose. Here’s how it would look with promises
const recordTime = (makeRequest) => {
const timeStart = Date.now();
makeRequest().then(() => { // throws error for sync functions (.then is not a function)
const timeEnd = Date.now();
console.log(‘time take:’, timeEnd - timeStart);
})
}
You know that all API calls are going to return promises, but what happens if you use the same function to record the time taken in a synchronous function? It will throw an error because the sync function does not return a promise. The usual way to avoid this is wrapping makeRequest()
in Promise.resolve()
If you use async/await, you won’t have to worry about these cases because await allows you to work safely with any value, promise or not.
const recordTime = async (makeRequest) => {
const timeStart = Date.now();
await makeRequest(); // works for any sync or async function
const timeEnd = Date.now();
console.log(‘time take:’, timeEnd - timeStart);
}
Async/await is one of the most revolutionary features that have been added to JavaScript in the past few years. It makes you realize what a syntactical mess promises are, and provides an intuitive replacement.
Some valid skepticism you might have about using async/await is that it makes asynchronous code less obvious: Our eyes learned to spot asynchronous code whenever we see a callback or a .then
, it will take a few weeks for your eyes to adjust to the new signs, but C# had this feature for years and people who are familiar with it know it’s worth this minor, temporary inconvenience.
Originally published by Mostafa Gaafar at hackernoon.com
===========================================
Thanks for reading :heart: If you liked this post, share it with all of your programming buddies! Follow me on Facebook | Twitter
☞ Svelte.js - The Complete Guide
☞ The Complete JavaScript Course 2019: Build Real Projects!
☞ Become a JavaScript developer - Learn (React, Node,Angular)
☞ JavaScript: Understanding the Weird Parts
☞ JavaScript: Coding Challenges Bootcamp - 2019
☞ The Complete Node.js Developer Course (3rd Edition)
☞ Angular & NodeJS - The MEAN Stack Guide
☞ NodeJS - The Complete Guide (incl. MVC, REST APIs, GraphQL)
☞ Node.js Absolute Beginners Guide - Learn Node From Scratch
#javascript #web-development
1600929360
We all know the importance of promises in our life. We even have a special day dedicated to it :) But how well do we know the importance of promises in JavaScript? Well if you don’t know it yet, it’s a great time to know it because they are becoming more and more popular. So what are promises? Let’s try to understand it through an analogy.
Suppose you are a top class rapper and you haven’t released an album for a while and fans are asking for it day and night. So what you do is that you “promise” them that whenever it will be out, all of them would be notified. To get this done you give your fans a list. They can fill in their email addresses, so that when the album becomes available, all the subscribers instantly receive it. And even if something goes wrong, say a pandemic, so that you can’t release the album, they will still be notified.
Now everyone is happy: You, because the people don’t crowd you anymore, and fans, because they won’t miss any news on the album.
This is a real-life analogy for things we often have in programming:
JavaScript promises are much more complex than a simple subscription list: they have additional features and limitations. But it’s fine to begin with.
#async #promises #javascript #development #await
1602406920
Promises in JavaScript are used to handle asynchronous operations by keeping track of whether a certain event has happened. If that certain event has taken place, it determines what happens next. Promises return a value which is either a resolved value or a reason why it’s rejected. They can handle multiple asynchronous operations easily and they provide better error handling than callbacks and events.
Callback: A callback is a function that is passed into another function as an argument to be executed later.
Events: Events provide a dynamic interface to a WebPage and are connected to elements in the Document Object Model(DOM), for example: onclick(), onmouseover() etc.
Pending: Before the event has happened, the promise is in the pending state.
Settled: Once the event has happened it is then in the settled state.
Fulfilled: Action related to the promise has succeeded.
Rejected: Action related to the promise has failed.
#javascript #javascript-development #javascript-tutorial #promises #javascript-tips
1564711349
Originally published by Mostafa Gaafar at hackernoon.com
For those who have never heard of this topic before, here’s a quick intro
Assuming a function getJSON
that returns a promise, and that promise resolves with some JSON object. We just want to call it and log that JSON, then return "done"
.
This is how you would implement it using promises
const makeRequest = () => getJSON() .then(data => { console.log(data) return "done" })makeRequest()
And this is how it looks with async/await
const makeRequest = async () => {
console.log(await getJSON())
return “done”
}makeRequest()
There are a few differences here
async
before it. The await
keyword can only be used inside functions defined with async
. Any async
function returns a promise implicitly, and the resolve value of the promise will be whatever you return
from the function (which is the string “done”
in our case).await
at the top level of our code since that is not inside an async
function.// this will not work in top level
// await makeRequest()// this will work
makeRequest().then((result) => {
// do something
})
3. await getJSON() means that the console.log
call will wait until getJSON()
promise resolves and print its value.
1. Concise and clean
Look at how much code we didn’t write! Even in the contrived example above, it’s clear we saved a decent amount of code. We didn’t have to write .then
, create an anonymous function to handle the response, or give a name data
to a variable that we don’t need to use. We also avoided nesting our code. These small advantages add up quickly, which will become more obvious in the following code examples.
2. Error handling
Async/await makes it finally possible to handle both synchronous and asynchronous errors with the same construct, good old try/catch
. In the example below with promises, the try/catch
will not handle if JSON.parse
fails because it’s happening inside a promise. We need to call .catch
on the promise and duplicate our error handling code, which will (hopefully) be more sophisticated than console.log
in your production-ready code.
const makeRequest = () => {
try {
getJSON()
.then(result => {
// this parse may fail
const data = JSON.parse(result)
console.log(data)
})
// uncomment this block to handle asynchronous errors
// .catch((err) => {
// console.log(err)
// })
} catch (err) {
console.log(err)
}
}
Now look at the same code with async/await. The catch
block now will handle parsing errors.
const makeRequest = async () => {
try {
// this parse may fail
const data = JSON.parse(await getJSON())
console.log(data)
} catch (err) {
console.log(err)
}
}
3. Conditionals
Imagine something like the code below which fetches some data and decides whether it should return that or get more details based on some value in the data.
const makeRequest = () => {
return getJSON()
.then(data => {
if (data.needsAnotherRequest) {
return makeAnotherRequest(data)
.then(moreData => {
console.log(moreData)
return moreData
})
} else {
console.log(data)
return data
}
})
}
Just looking at this gives you a headache. It’s easy to get lost in all that nesting (6 levels), braces, and return statements that are only needed to propagate the final result up to the main promise.
This example becomes way more readable when rewritten with async/await.
const makeRequest = async () => {
const data = await getJSON()
if (data.needsAnotherRequest) {
const moreData = await makeAnotherRequest(data);
console.log(moreData)
return moreData
} else {
console.log(data)
return data
}
}
4. Intermediate values
You have probably found yourself in a situation where you call a promise1
and then use what it returns to call promise2
, then use the results of both promises to call a promise3
. Your code most likely looked like this
const makeRequest = () => {
return promise1()
.then(value1 => {
// do something
return promise2(value1)
.then(value2 => {
// do something
return promise3(value1, value2)
})
})
}
If promise3
didn’t require value1
it would be easy to flatten the promise nesting a bit. If you are the kind of person who couldn’t live with this, you could wrap both values 1 & 2 in a Promise.all
and avoid deeper nesting, like this
const makeRequest = () => {
return promise1()
.then(value1 => {
// do something
return Promise.all([value1, promise2(value1)])
})
.then(([value1, value2]) => {
// do something
return promise3(value1, value2)
})
}
This approach sacrifices semantics for the sake of readability. There is no reason for value1
& value2
to belong in an array together, except to avoid nesting promises.
This same logic becomes ridiculously simple and intuitive with async/await. It makes you wonder about all the things you could have done in the time that you spent struggling to make promises look less hideous.
const makeRequest = async () => {
const value1 = await promise1()
const value2 = await promise2(value1)
return promise3(value1, value2)
}
5. Error stacks
Imagine a piece of code that calls multiple promises in a chain, and somewhere down the chain, an error is thrown.
const makeRequest = () => {
return callAPromise()
.then(() => callAPromise())
.then(() => callAPromise())
.then(() => callAPromise())
.then(() => callAPromise())
.then(() => {
throw new Error(“oops”);
})
}makeRequest()
.catch(err => {
console.log(err);
// output
// Error: oops at callAPromise.then.then.then.then.then (index.js:8:13)
})
The error stack returned from a promise chain gives no clue of where the error happened. Even worse, it’s misleading; the only function name it contains is callAPromise
which is totally innocent of this error (the file and line number are still useful though).
However, the error stack from async/await points to the function that contains the error
const makeRequest = async () => {
await callAPromise()
await callAPromise()
await callAPromise()
await callAPromise()
await callAPromise()
throw new Error(“oops”);
}makeRequest()
.catch(err => {
console.log(err);
// output
// Error: oops at makeRequest (index.js:7:9)
})
makeRequest
is better than knowing that the error came from a then
after a then
after a then
…Debugging
6. A killer advantage when using async/await is that it’s much easier to debug. Debugging promises has always been such a pain for 2 reasons
Try setting a breakpoint anywhere here
2. If you set a breakpoint inside a .then
block and use debug shortcuts like step-over, the debugger will not move to the following .then
because it only “steps” through synchronous code.
With async/await you don’t need arrow functions as much, and you can step through await calls exactly as if they were normal synchronous calls.
7. You can await
anything
Last but not least, await
can be used for both synchronous and asynchronous expressions. For example, you can write await 5
, which is equivalent to Promise.resolve(5)
. This might not seem very useful at first, but it’s actually a great advantage when writing a library or a utility function where you don’t know whether the input will be sync or async.
Imagine you want to record the time taken to execute some API calls in your application, and you decide to create a generic function for this purpose. Here’s how it would look with promises
const recordTime = (makeRequest) => {
const timeStart = Date.now();
makeRequest().then(() => { // throws error for sync functions (.then is not a function)
const timeEnd = Date.now();
console.log(‘time take:’, timeEnd - timeStart);
})
}
You know that all API calls are going to return promises, but what happens if you use the same function to record the time taken in a synchronous function? It will throw an error because the sync function does not return a promise. The usual way to avoid this is wrapping makeRequest()
in Promise.resolve()
If you use async/await, you won’t have to worry about these cases because await allows you to work safely with any value, promise or not.
const recordTime = async (makeRequest) => {
const timeStart = Date.now();
await makeRequest(); // works for any sync or async function
const timeEnd = Date.now();
console.log(‘time take:’, timeEnd - timeStart);
}
Async/await is one of the most revolutionary features that have been added to JavaScript in the past few years. It makes you realize what a syntactical mess promises are, and provides an intuitive replacement.
Some valid skepticism you might have about using async/await is that it makes asynchronous code less obvious: Our eyes learned to spot asynchronous code whenever we see a callback or a .then
, it will take a few weeks for your eyes to adjust to the new signs, but C# had this feature for years and people who are familiar with it know it’s worth this minor, temporary inconvenience.
Originally published by Mostafa Gaafar at hackernoon.com
===========================================
Thanks for reading :heart: If you liked this post, share it with all of your programming buddies! Follow me on Facebook | Twitter
☞ Svelte.js - The Complete Guide
☞ The Complete JavaScript Course 2019: Build Real Projects!
☞ Become a JavaScript developer - Learn (React, Node,Angular)
☞ JavaScript: Understanding the Weird Parts
☞ JavaScript: Coding Challenges Bootcamp - 2019
☞ The Complete Node.js Developer Course (3rd Edition)
☞ Angular & NodeJS - The MEAN Stack Guide
☞ NodeJS - The Complete Guide (incl. MVC, REST APIs, GraphQL)
☞ Node.js Absolute Beginners Guide - Learn Node From Scratch
#javascript #web-development
1602147513
icrosoft has released a new series of video tutorials on YouTube for novice programmers to get a hands-on renowned programming language — JavaScript.
This isn’t the first attempt by Microsoft to come up with video tutorials by beginner programmers. The company also has a series of YouTube tutorials on Python for beginners.
For JavaScript, Microsoft has launched a series of 51 videos as ‘Beginner’s Series to JavaScript,’ for young programmers, developers and coders who are interested in building browser applications using JavaScript. These video tutorials will also help programmers and coders to use relevant software development kits (SDKs) and JavaScript frameworks, such as Google’s Angular.
“Learning a new framework or development environment is made even more difficult when you don’t know the programming language,” stated on the Microsoft Developer channel on YouTube. “Fortunately, we’re here to help! We’ve created this series of videos to focus on the core concepts of JavaScript.”
It further stated — while the tutorials don’t cover every aspect of JavaScript, it indeed will help in building a foundation from which one can continue to grow. By the end of this series, Microsoft claims that the novice programmers will be able to work through tutorials, quick starts, books, and other resources, continuing to grow on their own.
#news #javascript #javascript tutorial #javascript tutorials #microsoft tutorials on javascript
1608042336
#shopping cart javascript #hopping cart with javascript #javascript shopping cart tutorial for beginners #javascript cart project #javascript tutorial #shopping cart