Understanding Promises in JavaScript: A Comprehensive Guide

Promises give us the option to perform asynchronous computation easily and more simply.

before Promises callbacks were used which leads to callback Hell,

to overcome this Problem Promises were introduced. 

Example of promises

const timer = time => new Promise((resolve,reject)=> setTimeout(resolve(“promise is resolved.”),time));

timer(3000)

.then((val)=> console.log(“Timer executeds — “+val))

.catch((err)=> console.log(” promise is rejected — “+err))

.finally(()=>console.log(“Promise is closed”))

Promise consists of 3 state of execution –

  1. Before the result is ready, the Promise is pending.
  2. If a result is available, the Promise is fulfilled.
  3. If an error happens, the Promise is rejected.

Note: A Promise is settled if inside function logic is executed. (if it is either fulfilled or rejected). only once the promise is settled.

Inside the promise, there are two operations to change the state. After you have invoked either one of them once.

  1. resolve – promise has been executed properly.
  2. reject – promise has been rejected.

How to consume the promises –

    .then() block handle the resolved output by promises.

    .error() block catch the error if the rejected state is sent by promise.

    .finally() block execute every time of resolve or reject of promise.

    Note – promise chaining is the concept where we can handle the resolved output by promises. in multiple. then blocks.

            .then()

            .then()

            .then()

What if we have multiple promises –

    There are methods provided by promises to handle all at once.

  • Promise.all() –  it is static method takes an iterable of promises as input and returns a single Promise when all promises are fulfilled.

const promise1 = Promise.resolve(1);

const promise2 = Promise.resolve(2);

const promise3 = Promise.resolve(3);

Promise.all([promise1,promise2,promise3]).then((values)=>{

    console.log(“all promises values – “,values);

})

  • Promise.allSettled() – it is static method takes an iterable of promises as input and returns a single Promise when all promises are settled. ( either it may resolve or reject. )

const promise4 = Promise.resolve(4);

const promise5 = Promise.resolve(5);

const promise6 = Promise.reject(6);

Promise.allSettled([promise4,promise5,promise6]).then((values)=>{

    console.log(“all promises values – “,values);

})

  • Promise.any() = static method takes an iterable of promises as input and returns a single Promise.

    This returned promise is fulfilled when any of the input’s promises are fulfilled, with this first fulfillment value.

   note – if any one of the rejected promises comes then also it will give output.

const promise7 = Promise.reject(0);

const promise8 = new Promise((resolve) => setTimeout(resolve, 100, ‘quick’));

const promise9 = new Promise((resolve) => setTimeout(resolve, 500, ‘slow’));

Promise.any([promise7,promise8,promise9]).then((values)=>{

    console.log(“all promises values – “,values);

})

  • Promise.race() = static method takes an iterable of promises as input and returns a single Promise.

    This returned promise settles with the eventual state of the first promise that settles

    note – if any one of the rejected promises comes then also it will give error.

// const promise11 = Promise.reject(0);

const promise11 = new Promise((resolve) => setTimeout(resolve, 100, ‘quick’));

const promise12 = new Promise((resolve) => setTimeout(resolve, 500, ‘slow’));

Promise.race([promise11,promise12]).then((values)=>{

    console.log(“all promises values – “,values);

})

basically both below used to This function flattens nested layers of promises.

Promise.resolve() – return promise resolve with value.

Promise.reject() – return the promise rejected.

Advantages of promises:

  1. Easy to Read Code and maintain.
  2. Advantage over callbacks.
  3. can handle multiple asynchronous tasks.

Disadvantages of promises:

  1. Complex Error Handling.
  2. For beginners it will create confusion.
  3. Hard Debugging error.

At the end – Promises is a Great Tool to handle Async Tasks. By using Async await we can handle Promises a lot easy way.

Flutter VS React Native: Which to choose?

Flutter and React Native are both mobile app development framework for building cross-platform applications for android and IOS with a single codebase, but each have unique features and strengths that make them suitable for different use case.

Overview

Flutter:

Flutter is cross-platform framework developed by google in 2017 , it is open-source UI toolkit that allows developers to create application for mobile, web and desktop from single codebase. Flutter uses the dart programming language and provides a rich set of pre-designed widgets that enable developers to create beautiful, fast, and highly customizable UI.

React Native:

React native is cross-platform framework developed by Facebook in 2015 and is popular framework enable to developers to build mobile using javascript and React, it allows to create apps that render natively across platfoms by using native components and has large ecosystem of third-party libraries and tools.

Difference between Flutter and React native

Programming language

Flutter:

Uses Dart programming language, a less widely used language compare to JavaScript. Dart is easy to learn.

React Native:

Uses JavaScript language, the most popular language for web development.  React library, making it easier for web developers to transition into mobile app development.

Performance

Flutter:

Known for its high performance. Flutter apps are compiled directly to native machine code, which reduces the performance overhead of JavaScript bridges in React native. This makes Flutter a strong choice for apps that require smooth animations or complex graphic.

React Native:

General performs well but can experience performance issues due to the JavaScript bridges that connects JavaScript code to native components. For most use case, the performance is sufficient, but apps with heavy animations or complex interaction might encounter limitation.

Development Experience

Flutter:

Flutter Providers a highly productive development experience with its HOT RELOAD feature, which allows developers to see changes instantly without losing the app state. Flutter also has excellent documentation and robust set of developer tools.

React Native:

React native also support FAST REFRESH, a similar feature to Flutter’s HOT RELOAD. React Native benefits from large community and extensive resources, but some developers report challenging with managing compatibility issues across different devices and platforms.

UI Components

Flutter:

Flutter uses customizable widgets that replace native platform components, widgets are highly customizable, so you can have more control over the look and design of your app.

React Native:

React Native uses native components for IOS and Android, UI components look like platforms native UI components, so if IOS updates, the app will update too.

Community and Ecosystem

Flutter:

Has a growing community and ecosystem, with increasing adoption by companies worldwide. While Flutter’s ecosystem is not as mature as React Native’s, it is rapidly expanding, especially after Google’s strong support and promotion.

React Native:

Has a large, mature community and ecosystem due to its longer time in the market. There are numerous third-party libraries, plugins, and tools available to speed up development and solve common challenges.

Platforms

Flutter:

Support  mobile (IOS and Android), Web and desktop (Windows and MacOS, Linux), This makes Flutter a versatile choice for developers looking to build applications across multiple platforms.

React Native:

Primarily focused on mobile platforms (iOS and Android).

When to choose Flutter:

  • High Performance: If your app requires high performance, especially with complex animations, graphics or real-time updates.
  • Custom UI: if you need highly customized UI that looks consistent across platforms, Flutter’s rich set of widgets and customizable rendering engine.
  • Multi-Platform: If you plan to support not only mobile but also web, desktop, or embedded devices, Flutter’s cross-platform capabilities can save significant development time and effort.

When to choose React Native:

  • JavaScript Familiarity: If your team is already proficient in JavaScript or React, adopting React Native can reduce the learning curve and speed up development.
  • Native Look: If you want your app to have a more “native” appearance and leverage native components, React Native might be a better fit.
  • Large Ecosystem: If you need access to a vast ecosystem of third-party libraries, plugins, and tools, React Native’s mature community can provide valuable resources.

Conclusion

Both Flutter and React Native are powerful Framework for cross-platform app development, each with its own set of advantages and challenges. To chose which framework to use will depend on specific project requirements

Call, Apply, Bind – Understanding Basic Concepts of JavaScript

In programming languages, you have a this keyword. The “this” keyword lets you refer to an object from within that object. “this”‘s value will change depending on the context that “this” is called in. By default it refers to the global scope, but when called within a function, it refers to that function.

Note – To understand call, apply, and bind you need to have good knowledge of how “this” works in JavaScript.

call(), apply(), and bind() can refer “this” to object.

 This let’s you to change the context of this when you invoke the function. It depends on how we are invoking the function.

1) Call:

Call method takes input as an String args comma seperated. call() provides a new value of this to the function/method. With call(), you can write a method once and then inherit it in another object, without having to rewrite the method for the new object.

                ex –

                const commonMethods = {

    fullname : function(city,state){

        return this.fname + ” ” + this.lname + ” Lives in ” + city + ” – ” + state;

    }

                }

                const Hero_1 = {

                    fname : “Tony”,

                    lname : “Stark”

                };

                const Hero_2 = {

                    fname : “Steve”,

                    lname : “Rogers”

                }

                const Hero_1_Details = commonMethods.fullname.call(Hero_1,”Malibu Point”,”USA”);

                const Hero_2_Details = commonMethods.fullname.call(Hero_2,”Washington, D.C.”,”USA”);

                console.log(Hero_1_Details);

                console.log(Hero_2_Details);



2) Apply:

It is same as call but different in passing the arguments in. The apply() method calls the specified function with a given this value, and arguments provided as an array (or an array-like object). apply() accepts a single array of arguments — for example, func.apply(this, [‘eat’, ‘bananas’]);

                ex :

                                const commonMethods = {

    fullname : function(city,state){

        return this.fname + ” ” + this.lname + ” Lives in ” + city + ” – ” + state;

    }

                }

                const Hero_1 = {

                    fname : “Tony”,

                    lname : “Stark”

                };

                const Hero_2 = {

                    fname : “Steve”,

                    lname : “Rogers”

                }

                const Hero_1_Details = commonMethods.fullname.apply(Hero_1,[“Malibu Point”,”USA”]);

                const Hero_2_Details = commonMethods.fullname.apply(Hero_2,[“Washington, D.C.”,”USA”]);

                console.log(Hero_1_Details);

                console.log(Hero_2_Details);

 



3) Bind:

The bind() method creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called. With the bind() method, an object can borrow a method from another object.

                const Hero_1 = {

                    fname : “Tony”,

                    lname : “Stark”,

                    fullname : function(city,state){

                        return this.fname + ” ” + this.lname + ” Lives in ” + city + ” – ” + state;

                    }

                };

                const Hero_2 = {

                    fname : “Steve”,

                    lname : “Rogers”,

                    showSuperPower : function(power){

                        return `Super Power is ${power}`

                    }

                }

                // here we have interchanged the function of each other. (showSuperPower and fullname)

                const Hero_2_Details = Hero_1.fullname.bind(Hero_2);

                console.log(Hero_2_Details(“Washington, D.C.”,”USA”));

                // Or

                const Hero_1_Details = Hero_2.showSuperPower.bind(Hero_1);

                console.log(Hero_1.fullname(“Malibu Point”,”USA”) + ” – and ” +Hero_1_Details(“Can Fly”));



Pros of using call apply bind:

  1. Code duplication removed.
  2. We can create a new function and bind with existing.
  3. Readability improves.

Cons of using call apply bind:

Basic concepts of Scops and “this” keyword must be strong else find hard to read and debug

Conclusion:

From the article, we’ve explored the foundational concepts of JavaScript. We’ll be adding more articles soon to delve deeper into the subject.

Thank you for reading!

Career Hire Us
Request Callback

Got An Idea?

Let’s Build It.

Tell us what you need, and our team will guide you from concept to launch with clarity, speed, and expert care.