1579794180
In this crash course we will look at asynchronous JavaScript and cover callbacks, promises including promise.all as well as the async / await syntax.
Today we're going to build and run an ice cream shop and learn asynchronous JavaScript at the same time. Along the way, you'll learn how to use:
Here's what we'll cover in this article:
So let's dive in!
What is Asynchronous JavaScript?
If you want to build projects efficiently, then this concept is for you.
The theory of async JavaScript helps you break down big complex projects into smaller tasks.
Then you can use any of these three techniques – callbacks, promises or Async/await – to run those small tasks in a way that you get the best results.
Let's dive in!🎖️
Synchronous vs Asynchronous JavaScript
In a synchronous system, tasks are completed one after another.
Think of this as if you have just one hand to accomplish 10 tasks. So, you have to complete one task at a time.
Take a look at the GIF 👇 – one thing is happening at a time here:
You'll see that until the first image is loaded completely, the second image doesn't start loading.
Well, JavaScript is by default Synchronous [single threaded]. Think about it like this – one thread means one hand with which to do stuff.
In this system, tasks are completed independently.
Here, imagine that for 10 tasks, you have 10 hands. So, each hand can do each task independently and at the same time.
Take a look at the GIF 👇 – you can see that each image loads at the same time.
Again, all the images are loading at their own pace. None of them is waiting for any of the others.
When three images are on a marathon, in a:
Before starting our project, let's look at some examples and clear up any doubts.
To test a synchronous system, write this code in JavaScript:
console.log(" I ");
console.log(" eat ");
console.log(" Ice Cream ");
Here's the result in the console: 👇
Let's say it takes two seconds to eat some ice cream. Now, let's test out an asynchronous system. Write the below code in JavaScript.
Note: Don't worry, we'll discuss the setTimeout()
function later in this article.
console.log("I");
// This will be shown after 2 seconds
setTimeout(()=>{
console.log("eat");
},2000)
console.log("Ice Cream")
And here's the result in the console: 👇
Now that you know the difference between synchronous and async operations, let's build our ice cream shop.
For this project you can just open Codepen.io and start coding. Or, you can do it in VS code or the editor of your choice.
Open the JavaScript section, and then open your developer console. We'll write our code and see the results in the console.
What are Callbacks in JavaScript?
When you nest a function inside another function as an argument, that's called a callback.
Here's an illustration of a callback:
An example of a callback
Don't worry, we'll see some examples of callbacks in a minute.
When doing a complex task, we break that task down into smaller steps. To help us establish a relationship between these steps according to time (optional) and order, we use callbacks.
Take a look at this example:👇
Chart contains steps to make ice cream
These are the small steps you need to take to make ice cream. Also note that in this example, the order of the steps and timing are crucial. You can't just chop the fruit and serve ice cream.
At the same time, if a previous step is not completed, we can't move on to the next step.
To explain that in more detail, let's start our ice cream shop business.
The shop will have two parts:
Now, we're gonna store our ingredients inside an object. Let's start!
You can store the ingredients inside objects like this: 👇
let stocks = {
Fruits : ["strawberry", "grapes", "banana", "apple"]
}
Our other ingredients are here: 👇
You can store these other ingredients in JavaScript objects like this: 👇
let stocks = {
Fruits : ["strawberry", "grapes", "banana", "apple"],
liquid : ["water", "ice"],
holder : ["cone", "cup", "stick"],
toppings : ["chocolate", "peanuts"],
};
The entire business depends on what a customer orders. Once we have an order, we start production and then we serve ice cream. So, we'll create two functions ->
order
production
This is how it all works: 👇
Get order from customer, fetch ingredients, start production, then serve.
Let's make our functions. We'll use arrow functions here:
let order = () =>{};
let production = () =>{};
Now, let's establish a relationship between these two functions using a callback, like this: 👇
let order = (call_production) =>{
call_production();
};
let production = () =>{};
We'll use the console.log()
function to conduct tests to clear up any doubts we might have regarding how we established the relationship between the two functions.
let order = (call_production) =>{
console.log("Order placed. Please call production")
// function 👇 is being called
call_production();
};
let production = () =>{
console.log("Production has started")
};
To run the test, we'll call the order
function. And we'll add the second function named production
as its argument.
// name 👇 of our second function
order(production);
Here's the result in our console 👇
So far so good – take a break!
Keep this code and remove everything [don't delete our stocks variable]. On our first function, pass another argument so that we can receive the order [Fruit name]:
// Function 1
let order = (fruit_name, call_production) =>{
call_production();
};
// Function 2
let production = () =>{};
// Trigger 👇
order("", production);
Here are our steps, and the time each step will take to execute.
Chart contains steps to make ice cream
In this chart, you can see that step 1 is to place the order, which takes 2 seconds. Then step 2 is cut the fruit (2 seconds), step 3 is add water and ice (1 second), step 4 is to start the machine (1 second), step 5 is to select the container (2 seconds), step 6 is to select the toppings (3 seconds) and step 7, the final step, is to serve the ice cream which takes 2 seconds.
To establish the timing, the function setTimeout()
is excellent as it is also uses a callback by taking a function as an argument.
Syntax of a setTimeout() function
Now, let's select our fruit and use this function:
// 1st Function
let order = (fruit_name, call_production) =>{
setTimeout(function(){
console.log(`${stocks.Fruits[fruit_name]} was selected`)
// Order placed. Call production to start
call_production();
},2000)
};
// 2nd Function
let production = () =>{
// blank for now
};
// Trigger 👇
order(0, production);
And here's the result in the console: 👇
Note that the result is displayed after 2 seconds.
If you're wondering how we picked strawberry from our stock variable, here's the code with the format 👇
Don't delete anything. Now we'll start writing our production function with the following code.👇 We'll use arrow functions:
let production = () =>{
setTimeout(()=>{
console.log("production has started")
},0000)
};
And here's the result 👇
We'll nest another setTimeout
function in our existing setTimeout
function to chop the fruit. Like this: 👇
let production = () =>{
setTimeout(()=>{
console.log("production has started")
setTimeout(()=>{
console.log("The fruit has been chopped")
},2000)
},0000)
};
And here's the result 👇
If you remember, here are our steps:
Chart contains steps to make ice cream
Let's complete our ice cream production by nesting a function inside another function – this is also known as a callback, remember?
let production = () =>{
setTimeout(()=>{
console.log("production has started")
setTimeout(()=>{
console.log("The fruit has been chopped")
setTimeout(()=>{
console.log(`${stocks.liquid[0]} and ${stocks.liquid[1]} Added`)
setTimeout(()=>{
console.log("start the machine")
setTimeout(()=>{
console.log(`Ice cream placed on ${stocks.holder[1]}`)
setTimeout(()=>{
console.log(`${stocks.toppings[0]} as toppings`)
setTimeout(()=>{
console.log("serve Ice cream")
},2000)
},3000)
},2000)
},1000)
},1000)
},2000)
},0000)
};
And here's the result in the console 👇
Feeling confused?
This is called callback hell. It looks something like this (remember that code just above?): 👇
Illustration of Callback hell
What's the solution to this?
How to Use Promises to Escape Callback Hell
Promises were invented to solve the problem of callback hell and to better handle our tasks.
But first, take a break!
This is how a promise looks:
illustration of a promise format
Let's dissect promises together.
An illustration of the life of a promise
As the above charts show, a promise has three states:
Let's adopt promises to our ice cream production case study.
We need to understand four more things first ->
.finally
handlerLet's start our ice cream shop and understand each of these concepts one by one by taking baby steps.
If you remember, these are our steps and the time each takes to make ice cream"
Chart contains steps to make ice cream
For this to happen, let's create a variable in JavaScript: 👇
let is_shop_open = true;
Now create a function named order
and pass two arguments named time, work
:
let order = ( time, work ) =>{
}
Now, we're gonna make a promise to our customer, "We will serve you ice-cream" Like this ->
let order = ( time, work ) =>{
return new Promise( ( resolve, reject )=>{ } )
}
Our promise has 2 parts:
let order = ( time, work ) => {
return new Promise( ( resolve, reject )=>{
if( is_shop_open ){
resolve( )
}
else{
reject( console.log("Our shop is closed") )
}
})
}
Let's add the time and work factors inside our promise using a setTimeout()
function inside our if
statement. Follow me 👇
Note: In real life, you can avoid the time factor as well. This is completely dependent on the nature of your work.
let order = ( time, work ) => {
return new Promise( ( resolve, reject )=>{
if( is_shop_open ){
setTimeout(()=>{
// work is 👇 getting done here
resolve( work() )
// Setting 👇 time here for 1 work
}, time)
}
else{
reject( console.log("Our shop is closed") )
}
})
}
Now, we're gonna use our newly created function to start ice-cream production.
// Set 👇 time here
order( 2000, ()=>console.log(`${stocks.Fruits[0]} was selected`))
// pass a ☝️ function here to start working
The result 👇 after 2 seconds looks like this:
Good job!
In this method, we defining what we need to do when the first task is complete using the .then
handler. It looks something like this 👇
Illustration of promise chaining using .then handler
The .then handler returns a promise when our original promise is resolved.
Let me make it simpler: it's similar to giving instructions to someone. You tell someone to " First do this, then do that, then this other thing, then.., then.., then..." and so on.
Let's implement this on our project. At the bottom of your code write the following lines. 👇
Note: don't forget to write the return
word inside your .then
handler. Otherwise, it won't work properly. If you're curious, try removing the return once we finish the steps:
order(2000,()=>console.log(`${stocks.Fruits[0]} was selected`))
.then(()=>{
return order(0000,()=>console.log('production has started'))
})
And here's the result: 👇
Using the same system, let's finish our project:👇
// step 1
order(2000,()=>console.log(`${stocks.Fruits[0]} was selected`))
// step 2
.then(()=>{
return order(0000,()=>console.log('production has started'))
})
// step 3
.then(()=>{
return order(2000, ()=>console.log("Fruit has been chopped"))
})
// step 4
.then(()=>{
return order(1000, ()=>console.log(`${stocks.liquid[0]} and ${stocks.liquid[1]} added`))
})
// step 5
.then(()=>{
return order(1000, ()=>console.log("start the machine"))
})
// step 6
.then(()=>{
return order(2000, ()=>console.log(`ice cream placed on ${stocks.holder[1]}`))
})
// step 7
.then(()=>{
return order(3000, ()=>console.log(`${stocks.toppings[0]} as toppings`))
})
// Step 8
.then(()=>{
return order(2000, ()=>console.log("Serve Ice Cream"))
})
Here's the result: 👇
We need a way to handle errors when something goes wrong. But first, we need to understand the promise cycle:
An illustration of the life of a promise
To catch our errors, let's change our variable to false.
let is_shop_open = false;
Which means our shop is closed. We're not selling ice cream to our customers anymore.
To handle this, we use the .catch
handler. Just like .then
, it also returns a promise, but only when our original promise is rejected.
A small reminder here:
.then
works when a promise is resolved.catch
works when a promise is rejectedGo down to the very bottom and write the following code:👇
Just remember that there should be nothing between your previous .then
handler and the .catch
handler.
.catch(()=>{
console.log("Customer left")
})
Here's the result:👇
A couple things to note about this code:
reject()
part of our promise.catch
handlerThere's something called the finally
handler which works regardless of whether our promise was resolved or rejected.
For example: whether we serve no customers or 100 customers, our shop will close at the end of the day
If you're curious to test this, come at very bottom and write this code: 👇
.finally(()=>{
console.log("end of day")
})
The result:👇
Everyone, please welcome Async / Await~
How Does Async / Await Work in JavaScript?
This is supposed to be the better way to write promises and it helps us keep our code simple and clean.
All you have to do is write the word async
before any regular function and it becomes a promise.
Let's have a look:👇
Before async/await, to make a promise we wrote this:
function order(){
return new Promise( (resolve, reject) =>{
// Write code here
} )
}
Now using async/await, we write one like this:
//👇 the magical keyword
async function order() {
// Write code here
}
You need to understand ->
try
and catch
keywordsWe use the try
keyword to run our code while we use catch
to catch our errors. It's the same concept we saw when we looked at promises.
Let's see a comparison. We'll see a small demo of the format, then we'll start coding.
We used resolve and reject in promises like this:
function kitchen(){
return new Promise ((resolve, reject)=>{
if(true){
resolve("promise is fulfilled")
}
else{
reject("error caught here")
}
})
}
kitchen() // run the code
.then() // next step
.then() // next step
.catch() // error caught here
.finally() // end of the promise [optional]
When we're using async/await, we use this format:
//👇 Magical keyword
async function kitchen(){
try{
// Let's create a fake problem
await abc;
}
catch(error){
console.log("abc does not exist", error)
}
finally{
console.log("Runs code anyways")
}
}
kitchen() // run the code
Don't panic, we'll discuss the await
keyword next.
Now hopefully you understand the difference between promises and Async / Await.
The keyword await
makes JavaScript wait until a promise settles and returns its result.
Let's go back to our ice cream shop. We don't know which topping a customer might prefer, chocolate or peanuts. So we need to stop our machine and go and ask our customer what they'd like on their ice cream.
Notice here that only our kitchen is stopped, but our staff outside the kitchen will still do things like:
Let's create a small promise to ask which topping to use. The process takes three seconds.
function toppings_choice (){
return new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve( console.log("which topping would you love?") )
},3000)
})
}
Now, let's create our kitchen function with the async keyword first.
async function kitchen(){
console.log("A")
console.log("B")
console.log("C")
await toppings_choice()
console.log("D")
console.log("E")
}
// Trigger the function
kitchen();
Let's add other tasks below the kitchen()
call.
console.log("doing the dishes")
console.log("cleaning the tables")
console.log("taking orders")
And here's the result:
We are literally going outside our kitchen to ask our customer, "what is your topping choice?" In the mean time, other things still get done.
Once, we get their topping choice, we enter the kitchen and finish the job.
When using Async/ Await, you can also use the .then
, .catch
, and .finally
handlers as well which are a core part of promises.
We're gonna create two functions ->
kitchen
: to make ice creamtime
: to assign the amount of time each small task will take.Let's start! First, create the time function:
let is_shop_open = true;
function time(ms) {
return new Promise( (resolve, reject) => {
if(is_shop_open){
setTimeout(resolve,ms);
}
else{
reject(console.log("Shop is closed"))
}
});
}
Now, let's create our kitchen:
async function kitchen(){
try{
// instruction here
}
catch(error){
// error management here
}
}
// Trigger
kitchen();
Let's give small instructions and test if our kitchen function is working or not:
async function kitchen(){
try{
// time taken to perform this 1 task
await time(2000)
console.log(`${stocks.Fruits[0]} was selected`)
}
catch(error){
console.log("Customer left", error)
}
finally{
console.log("Day ended, shop closed")
}
}
// Trigger
kitchen();
The result looks like this when the shop is open: 👇
The result looks like this when the shop is closed: 👇
So far so good.
Let's complete our project.
Here's the list of our tasks again: 👇
Chart contains steps to make ice cream
First, open our shop
let is_shop_open = true;
Now write the steps inside our kitchen()
function: 👇
async function kitchen(){
try{
await time(2000)
console.log(`${stocks.Fruits[0]} was selected`)
await time(0000)
console.log("production has started")
await time(2000)
console.log("fruit has been chopped")
await time(1000)
console.log(`${stocks.liquid[0]} and ${stocks.liquid[1]} added`)
await time(1000)
console.log("start the machine")
await time(2000)
console.log(`ice cream placed on ${stocks.holder[1]}`)
await time(3000)
console.log(`${stocks.toppings[0]} as toppings`)
await time(2000)
console.log("Serve Ice Cream")
}
catch(error){
console.log("customer left")
}
}
And here's the result: 👇
Conclusion
Congratulations for reading until the end! In this article you've learned:
Here's your medal for reading until the end. ❤️
#javascript #programming #developer
1632537859
Not babashka. Node.js babashka!?
Ad-hoc CLJS scripting on Node.js.
Experimental. Please report issues here.
Nbb's main goal is to make it easy to get started with ad hoc CLJS scripting on Node.js.
Additional goals and features are:
Nbb requires Node.js v12 or newer.
CLJS code is evaluated through SCI, the same interpreter that powers babashka. Because SCI works with advanced compilation, the bundle size, especially when combined with other dependencies, is smaller than what you get with self-hosted CLJS. That makes startup faster. The trade-off is that execution is less performant and that only a subset of CLJS is available (e.g. no deftype, yet).
Install nbb
from NPM:
$ npm install nbb -g
Omit -g
for a local install.
Try out an expression:
$ nbb -e '(+ 1 2 3)'
6
And then install some other NPM libraries to use in the script. E.g.:
$ npm install csv-parse shelljs zx
Create a script which uses the NPM libraries:
(ns script
(:require ["csv-parse/lib/sync$default" :as csv-parse]
["fs" :as fs]
["path" :as path]
["shelljs$default" :as sh]
["term-size$default" :as term-size]
["zx$default" :as zx]
["zx$fs" :as zxfs]
[nbb.core :refer [*file*]]))
(prn (path/resolve "."))
(prn (term-size))
(println (count (str (fs/readFileSync *file*))))
(prn (sh/ls "."))
(prn (csv-parse "foo,bar"))
(prn (zxfs/existsSync *file*))
(zx/$ #js ["ls"])
Call the script:
$ nbb script.cljs
"/private/tmp/test-script"
#js {:columns 216, :rows 47}
510
#js ["node_modules" "package-lock.json" "package.json" "script.cljs"]
#js [#js ["foo" "bar"]]
true
$ ls
node_modules
package-lock.json
package.json
script.cljs
Nbb has first class support for macros: you can define them right inside your .cljs
file, like you are used to from JVM Clojure. Consider the plet
macro to make working with promises more palatable:
(defmacro plet
[bindings & body]
(let [binding-pairs (reverse (partition 2 bindings))
body (cons 'do body)]
(reduce (fn [body [sym expr]]
(let [expr (list '.resolve 'js/Promise expr)]
(list '.then expr (list 'clojure.core/fn (vector sym)
body))))
body
binding-pairs)))
Using this macro we can look async code more like sync code. Consider this puppeteer example:
(-> (.launch puppeteer)
(.then (fn [browser]
(-> (.newPage browser)
(.then (fn [page]
(-> (.goto page "https://clojure.org")
(.then #(.screenshot page #js{:path "screenshot.png"}))
(.catch #(js/console.log %))
(.then #(.close browser)))))))))
Using plet
this becomes:
(plet [browser (.launch puppeteer)
page (.newPage browser)
_ (.goto page "https://clojure.org")
_ (-> (.screenshot page #js{:path "screenshot.png"})
(.catch #(js/console.log %)))]
(.close browser))
See the puppeteer example for the full code.
Since v0.0.36, nbb includes promesa which is a library to deal with promises. The above plet
macro is similar to promesa.core/let
.
$ time nbb -e '(+ 1 2 3)'
6
nbb -e '(+ 1 2 3)' 0.17s user 0.02s system 109% cpu 0.168 total
The baseline startup time for a script is about 170ms seconds on my laptop. When invoked via npx
this adds another 300ms or so, so for faster startup, either use a globally installed nbb
or use $(npm bin)/nbb script.cljs
to bypass npx
.
Nbb does not depend on any NPM dependencies. All NPM libraries loaded by a script are resolved relative to that script. When using the Reagent module, React is resolved in the same way as any other NPM library.
To load .cljs
files from local paths or dependencies, you can use the --classpath
argument. The current dir is added to the classpath automatically. So if there is a file foo/bar.cljs
relative to your current dir, then you can load it via (:require [foo.bar :as fb])
. Note that nbb
uses the same naming conventions for namespaces and directories as other Clojure tools: foo-bar
in the namespace name becomes foo_bar
in the directory name.
To load dependencies from the Clojure ecosystem, you can use the Clojure CLI or babashka to download them and produce a classpath:
$ classpath="$(clojure -A:nbb -Spath -Sdeps '{:aliases {:nbb {:replace-deps {com.github.seancorfield/honeysql {:git/tag "v2.0.0-rc5" :git/sha "01c3a55"}}}}}')"
and then feed it to the --classpath
argument:
$ nbb --classpath "$classpath" -e "(require '[honey.sql :as sql]) (sql/format {:select :foo :from :bar :where [:= :baz 2]})"
["SELECT foo FROM bar WHERE baz = ?" 2]
Currently nbb
only reads from directories, not jar files, so you are encouraged to use git libs. Support for .jar
files will be added later.
The name of the file that is currently being executed is available via nbb.core/*file*
or on the metadata of vars:
(ns foo
(:require [nbb.core :refer [*file*]]))
(prn *file*) ;; "/private/tmp/foo.cljs"
(defn f [])
(prn (:file (meta #'f))) ;; "/private/tmp/foo.cljs"
Nbb includes reagent.core
which will be lazily loaded when required. You can use this together with ink to create a TUI application:
$ npm install ink
ink-demo.cljs
:
(ns ink-demo
(:require ["ink" :refer [render Text]]
[reagent.core :as r]))
(defonce state (r/atom 0))
(doseq [n (range 1 11)]
(js/setTimeout #(swap! state inc) (* n 500)))
(defn hello []
[:> Text {:color "green"} "Hello, world! " @state])
(render (r/as-element [hello]))
Working with callbacks and promises can become tedious. Since nbb v0.0.36 the promesa.core
namespace is included with the let
and do!
macros. An example:
(ns prom
(:require [promesa.core :as p]))
(defn sleep [ms]
(js/Promise.
(fn [resolve _]
(js/setTimeout resolve ms))))
(defn do-stuff
[]
(p/do!
(println "Doing stuff which takes a while")
(sleep 1000)
1))
(p/let [a (do-stuff)
b (inc a)
c (do-stuff)
d (+ b c)]
(prn d))
$ nbb prom.cljs
Doing stuff which takes a while
Doing stuff which takes a while
3
Also see API docs.
Since nbb v0.0.75 applied-science/js-interop is available:
(ns example
(:require [applied-science.js-interop :as j]))
(def o (j/lit {:a 1 :b 2 :c {:d 1}}))
(prn (j/select-keys o [:a :b])) ;; #js {:a 1, :b 2}
(prn (j/get-in o [:c :d])) ;; 1
Most of this library is supported in nbb, except the following:
:syms
.-x
notation. In nbb, you must use keywords.See the example of what is currently supported.
See the examples directory for small examples.
Also check out these projects built with nbb:
See API documentation.
See this gist on how to convert an nbb script or project to shadow-cljs.
Prequisites:
To build:
bb release
Run bb tasks
for more project-related tasks.
Download Details:
Author: borkdude
Download Link: Download The Source Code
Official Website: https://github.com/borkdude/nbb
License: EPL-1.0
#node #javascript
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
1590245760
Base on developer requirement we are going to cover promises and async/await with this article. Some developers are still confused about how to use promises and async javascript. JavaScript Promises are very similar to real-life promises made by us. After that promises, we make a plan and assure that we are successfully have done or broke.
JS promises are completion or failure.
#async #await #javascript #js
1635908361
Attempting to use Async / Await with forEach is a bad idea. In this advance async/await Javascript tutorial, I'll show you why. You will learn how for, for...of, Promise.all(), and reduce all provide alternative solutions that are better than forEach.
Async Await with forEach is BAD! | Advanced Async/Await Javascript Tutorial
(00:00) Intro
(00:05) Welcome and Intro
(00:22) forEach - What's it good for?
(02:34) Async fetch request example
(03:51) forEach with Async Await is BAD
(07:33) Alternative #1: traditional for loop
(09:39) Alternative #2: for...of loop
(10:39) Alternative #3: Promise.all with map
(14:01) Alternative #4: A different reduce
📚 References:
MDN forEach:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach
MDN for...of:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of
MDN PromiseAll:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all
MDN reduce:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce
#javascript #js #foreach #async #await
1599295469
Let us understand term _Callback _by an real-world example: Suppose, you are calling to your Girlfriend (If you have) and she is busy in another call then she send message to you : “I am busy right now, Call back you later.!!”. After completing her work, she calls you back and this is what call back in JavaScript as well.
In JavaScript, When a function is executing (Girlfriend is talking with someone) then after function execution is completed another function is started for execution this is call back function.
Now you are thinking that its depend upon when, where you are calling function and all function call is “Call-back function”.
Here, _printWorld() _function is executed after _printHello() _complete its execution but this is not call-back function example because _printHello() _is not Asynchronous function. Suppose, _printHello() _prints after 1 Second then _printWorld() _executes first.
What if we want “Hello World” output when Asynchronous function is there. We can pass function as argument and calls it after _printHello() _complete its execution. Here below code snippet of how _function pass as argument _:
Callback function can be defined as a function passed by argument and executes when one function completes its execution.
Suppose, If you have API (Application Programming Interface) to get Students Roll numbers and select one of Roll number — getting that roll number’s data and print that data. We don’t have API to get students data so we are using _setTimeout() _Async function and getting roll number after 2s, We are also selecting one of roll number manually after 2s and print Roll number’s data after 2s. This can be done by call back function.
The program became complex and complex if we have too many things to do like Getting Students data, Selecting one of them student, get student’s roll number and get result by roll number then it become very complex. If you have any Error in this then debugging is also tedious task, this things is called “Callback Hell”, which is shape like “Pyramid Of Doom”.
To overcome with this problem, Promises is introduced in JavaScript. Promises has three states : Pending, Resolved, Reject. Promises is created by Constructor : new Promise(). It has one executor function which has two arguments (resolve, reject).
Promise object has three methods: then(), catch() & finally().
If Promise is successfully executed then its data is transferred through resolve function and if it has error then passed through reject function.
We have implemented same task which is done using call back function in Promises and its easily understandable However it is complicated compare to callback function but when you use promises for sometimes then it’s easy to implement.
In _getRollNumber(), _resolve method’s data is caught by then() functions arguments and reject method’s data is caught by catch() function. Here In Promises, Every task has different promises because of that it is easy to debug and readable compare to call back function. You can see that there is no shape like “Pyramid of Doom” in Promises. This is how Callback function is replaced by Promises.
Thank you for reading!
This article was originally published on Medium.com
#javascript-tips #advanced-javascript #javascript #callback-function #promises