Mrinal Raj

Mrinal Raj

1579794180

Asynchronous JavaScript | Callbacks, Promises, and Async/Await in JS

In this crash course we will look at asynchronous JavaScript and cover callbacks, promises including promise.all as well as the async / await syntax.


JavaScript Async/Await Tutorial – Learn Callbacks, Promises, and Async/Await in JS by Making Ice Cream 🍧🍨🍦

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:

  • Callbacks
  • Promises
  • Async / Await
Alt Text

Here's what we'll cover in this article:

  • What is Asynchronous JavaScript?
  • Synchronous vs Asynchronous JavaScript
  • How Callbacks Work in JavaScript
  • How Promises Work in JavaScript
  • How Async / Await Works in JavaScript

So let's dive in!

What is Asynchronous JavaScript?

Alt Text

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

What is a Synchronous System?

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:

Synchronous System

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.

What is an Asynchronous System?

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.

Asynchronous System

Again, all the images are loading at their own pace. None of them is waiting for any of the others.

To Summarize Synchronous vs Asynchronous JS:

When three images are on a marathon, in a:

  • Synchronous system, three images are in the same lane. One can't overtake the other. The race is finished one by one. If image number 2 stops, the following image stops.

Alt Text

  • Asynchronous system, the three images are in different lanes. They'll finish the race on their own pace. Nobody stops for anybody:

Alt Text

Synchronous and Asynchronous Code Examples

Alt Text

Before starting our project, let's look at some examples and clear up any doubts.

Synchronous Code Example

Alt Text

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: 👇

Alt Text

Asynchronous code example

Alt Text

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: 👇

Alt Text

Now that you know the difference between synchronous and async operations, let's build our ice cream shop.

How to Setup our Project

Alt Text

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?

Alt Text

When you nest a function inside another function as an argument, that's called a callback.

Here's an illustration of a callback:

uz3pl56lmoc2pq7wzi2s

An example of a callback

Don't worry, we'll see some examples of callbacks in a minute.

Why do we use callbacks?

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:👇

Alt Text

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.

Alt Text

To explain that in more detail, let's start our ice cream shop business.

But Wait...

Alt Text

The shop will have two parts:

  • The storeroom will have all the ingredients [Our Backend]
  • We'll produce ice cream in our kitchen [The frontend]

Alt Text

Let's store our data

Now, we're gonna store our ingredients inside an object. Let's start!

Alt Text

You can store the ingredients inside objects like this: 👇

let stocks = {
    Fruits : ["strawberry", "grapes", "banana", "apple"]
 }

Our other ingredients are here: 👇

Alt Text

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

Alt Text

This is how it all works: 👇

Alt Text

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 = () =>{};

Let's do a small test

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 👇

Alt Text

Take a break

So far so good – take a break!

Alt Text

Clear out the console.log

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.

Alt Text

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.

Alt Text

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.

Alt Text

If you're wondering how we picked strawberry from our stock variable, here's the code with the format 👇

Alt Text

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 👇

Alt Text

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 👇

Alt Text

If you remember, here are our steps:

Alt Text

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 👇

Alt Text

Feeling confused?

Alt Text

This is called callback hell. It looks something like this (remember that code just above?): 👇

Alt Text

Illustration of Callback hell

What's the solution to this?

How to Use Promises to Escape Callback Hell

Alt Text

Promises were invented to solve the problem of callback hell and to better handle our tasks.

Take a break

But first, take a break!

Alt Text

This is how a promise looks:

Alt Text

illustration of a promise format

Let's dissect promises together.

Alt Text

Alt Text

An illustration of the life of a promise

As the above charts show, a promise has three states:

  • Pending: This is the initial stage. Nothing happens here. Think of it like this, your customer is taking their time giving you an order. But they haven't ordered anything yet.
  • Resolved: This means that your customer has received their food and is happy.
  • Rejected: This means that your customer didn't receive their order and left the restaurant.

Let's adopt promises to our ice cream production case study.

But wait...

Alt Text

We need to understand four more things first ->

  • Relationship between time and work
  • Promise chaining
  • Error handling
  • The .finally handler

Let's start our ice cream shop and understand each of these concepts one by one by taking baby steps.

Relationship between time and work

If you remember, these are our steps and the time each takes to make ice cream"

Alt Text

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:

  • Resolved [ ice cream delivered ]
  • Rejected [ customer didn't get ice cream ]
let order = ( time, work ) => {

  return new Promise( ( resolve, reject )=>{

    if( is_shop_open ){

      resolve( )

    }

    else{

      reject( console.log("Our shop is closed") )

    }

  })
}

Alt Text

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:

Alt Text

Good job!

Alt Text

Promise chaining

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 👇

Alt Text

Illustration of promise chaining using .then handler

The .then handler returns a promise when our original promise is resolved.

Here's an Example:

Alt Text

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.

  • The first task is our original promise.
  • The rest of the tasks return our promise once one small bit of work is completed

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: 👇

Alt Text

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: 👇

Alt Text

Error handling

We need a way to handle errors when something goes wrong. But first, we need to understand the promise cycle:

Alt Text

Alt Text

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 rejected

Go 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:👇

Alt Text

A couple things to note about this code:

  • The 1st message is coming from the reject() part of our promise
  • The 2nd message is coming from the .catch handler

How to use the .finally() handler

Alt Text

There'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:👇

Alt Text

Everyone, please welcome Async / Await~

How Does Async / Await Work in JavaScript?

Alt Text

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.

But first, take a break

Alt Text

Let's have a look:👇

Alt Text

Promises vs Async/Await in JavaScript

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
 }

But wait......

Alt Text

You need to understand ->

  • How to use the try and catch keywords
  • How to use the await keyword

How to use the Try and Catch keywords

We 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.

Promises in JS -> resolve or reject

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]

Async / Await in JS -> try, catch

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.

How to Use JavaScript's Await Keyword

Alt Text

The keyword await makes JavaScript wait until a promise settles and returns its result.

How to use the await keyword in JavaScript

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:

  • doing the dishes
  • cleaning the tables
  • taking orders, and so on.

An Await Keyword Code Example

Alt Text

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:

Alt Text

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.

Small note

When using Async/ Await, you can also use the .then, .catch, and .finally  handlers as well which are a core part of promises.

Let's open our Ice cream shop again

Alt Text

We're gonna create two functions ->

  • kitchen: to make ice cream
  • time: 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: 👇

Alt Text

The result looks like this when the shop is closed: 👇

Alt Text

So far so good.

Alt Text

Let's complete our project.

Here's the list of our tasks again: 👇

Alt Text

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: 👇

Alt Text

Conclusion

Congratulations for reading until the end! In this article you've learned:

  • The difference between synchronous and asynchronous systems
  • Mechanisms of asynchronous JavaScript using 3 techniques (callbacks, promises, and Async/ Await)

Here's your medal for reading until the end. ❤️

#javascript #programming #developer 

What is GEEK

Buddha Community

Asynchronous JavaScript | Callbacks, Promises, and Async/Await in JS

NBB: Ad-hoc CLJS Scripting on Node.js

Nbb

Not babashka. Node.js babashka!?

Ad-hoc CLJS scripting on Node.js.

Status

Experimental. Please report issues here.

Goals and features

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:

  • Fast startup without relying on a custom version of Node.js.
  • Small artifact (current size is around 1.2MB).
  • First class macros.
  • Support building small TUI apps using Reagent.
  • Complement babashka with libraries from the Node.js ecosystem.

Requirements

Nbb requires Node.js v12 or newer.

How does this tool work?

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).

Usage

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

Macros

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.

Startup time

$ 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.

Dependencies

NPM dependencies

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.

Classpath

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.

Current file

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"

Reagent

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]))

Promesa

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.

Js-interop

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:

  • destructuring using :syms
  • property access using .-x notation. In nbb, you must use keywords.

See the example of what is currently supported.

Examples

See the examples directory for small examples.

Also check out these projects built with nbb:

API

See API documentation.

Migrating to shadow-cljs

See this gist on how to convert an nbb script or project to shadow-cljs.

Build

Prequisites:

  • babashka >= 0.4.0
  • Clojure CLI >= 1.10.3.933
  • Node.js 16.5.0 (lower version may work, but this is the one I used to build)

To build:

  • Clone and cd into this repo
  • 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

Giles  Goodwin

Giles Goodwin

1600929360

Understanding JavaScript: Promises, Async & Await!!

Analogy

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:

  1. “producing code” that does something and may take time. That’s a “rapper”.
  2. “consuming code” that wants the result of the “producing code” once it’s ready. Many functions may need that result. These are the “fans”.
  3. A promise is a special JavaScript object that links the “producing code” and the “consuming code” together. In terms of our analogy: this is the “subscription list”. The “producing code” takes whatever time it needs to produce the promised result, and the “promise” makes that result available to all of the subscribed code when it’s ready.

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

Armando  Bruen

Armando Bruen

1590245760

What is promise and Async/Await?

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

Async/Await with forEach is BAD! | Javascript Tutorial

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

Hugo JS

Hugo JS

1599295469

What is Callback-Function in JavaScript? How it is Replaced By Promises?

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”. Image for post

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.

Image for post

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 _:

Image for post

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.

Image for post

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().

Image for post

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