JavaScript Promises: The Definitive Guide, Part 1

JavaScript Promises: The Definitive Guide, Part 1

If you deal with Promises in Javascript, then you absolutely need to read this guide.

The single-threaded, event-loop based concurrency model of JavaScript deals with processing of events using so-called “asynchronous non-blocking I/O model.” Unlike computer languages such as Java, where events are handled using additional threads and processed in parallel with the main execution thread, JavaScript code is executed sequentially. In order to prevent blocking the main thread on I/O-bound operations, JavaScript uses a callback mechanism where asynchronous operations specify a callback – the function to be executed when the result of an asynchronous operation is ready; while the code control flow continues executing.

Whenever we want to use the result of a callback to make another asynchronous call, we need to nest callbacks. Since I/O operations can result in errors, we need to handle errors for each callback before processing the success result. This necessity to do error handling and having to embed callbacks makes the callback code difficult to read. Sometimes this is referred to as “JavaScript callback hell.”

In order to address this problem, JavaScript offers a mechanism called a Promise. It is a common programming paradigm (more about it here: https://en.wikipedia.org/wiki/Futures_and_promises) and TC39 introduced it in ECMAScript 2015. The JavaScript Promise is an object holding a state, which represents an eventual completion (or failure) of an asynchronous operation and its resulting value.

A new Promise is in the pending state. If a Promise succeeds it is put in a resolved state otherwise it is rejected. Instead of using the original callback mechanism, code using Promises creates a Promise object. We use Promises typically with two callback handlers – resolved invoked when the operation was successful and rejected called whenever an error has occurred.

// Converting a callback based method to a method that returns Promise
const fs = require('fs')

const readTextFromFile = new Promise((resolve, reject) => {
  fs.readFile('file.txt', (err, data) => {
    if (err) {
      return reject(err)
    }

    resolve(data)
  })
})

// Usage of a method that returns Promise
readTextFromFile()
  .then(data => console.log(data))
  .catch(e => console.log(e))

Process.nextTick(callback)

To understand how Promises work in Node.js, it is important to review how process.nextTick() works in Node.js, as the two are very similar. Process.nextTick() is a method that adds a callback to the “next tick queue.” Tasks in the queue are executed after the current operation in the event loop is done and before the event loop is allowed to continue. Simply said, there’s another queue beside the event loop that we can use to schedule events. This queue is even faster than the event loop and it may be drained several times in a single event loop tick.

const log = msg => () => console.log(`NEXT TICK ${msg}`)

const timeout = (time, msg) => {
  setTimeout(() => {
    console.log(`TIMEOUT ${msg}`)
  }, time)
}

process.nextTick(log('ONE'))
timeout(0, 'AFTER-ONE')
process.nextTick(log('TWO'))
timeout(0, 'AFTER-TWO')

In the example above, we can see how process.nextTick works in practice. We have two setTimeout calls, with callbacks immediately scheduled in the event loop. We also have two process.nextTick methods with callbacks scheduled in the “next tick queue.” This is what we see in the console:

Next TICK ONE
Next TICK TWO
TIMEOUT AFTER-ONE
TIMEOUT AFTER-TWO

Since we know that “next tick queue” is separate from event loop and can be drained multiple times in a single event loop tick, this makes sense. Two nextTick callbacks are executed immediately and the other two setTimeout callbacks, set in the event loop, are executed after.

Putting so many callbacks in the “next tick queue” may block the event loop and prevent any I/O operation. That’s why we have process.maxTickDepth that represents the maximum number of callbacks in the queue that can be executed before allowing the event loop to continue. Its default value is 1000.

How Do Promises Work?

Promises are a new and nice way to handle async code, but how do they really work? For understanding the benefits and the performance characteristics of Promises we need to understand how they are implemented and what really happens when we return new Promise() .

Promises use the Microtask queue and they are executed independently from regular tasks (the setTimeout callback, for example). What does this really mean? In JavaScript, we have three queues: (1) event loop, (2) nextTick queue and (3) Microtask queue. All those queues work independently.

Macrotasks are regular tasks that are going into the event loop and in one event loop tick, only one Macrotask is executed. Microtasks have an independent queue and, in one event-loop tick, the whole microtasks queue can be drained. This gives us a really good performance benefit. Basically, we use microtasks when we need to do stuff asynchronously in a synchronous way, as fast as possible.

Promises are executed as Microtasks. This means that they are executed sooner than Macrotasks. They are never executed concurrently. Microtasks are always executed sequentially, so talking about parallelism with Promises is wrong. They work like process.nextTick, independently from event loop in their own microtask queue.

Macrotasks: setTimeout, setInterval, setImmediate, requestAnimationFrame, I/O, UI rendering

Microtasks: process.nextTick, Promises, Object.observe, MutationObserver (read more here)

const fetch = require('node-fetch') // only when running in Node.js

const fetchData = fetch('https://api.github.com/users/nearform/repos')
  .then(() => console.log('Hi from fetch!'))
  .catch(e => console.error(e))

console.log('Hi!')

setTimeout(() => {
  console.log('Hi from setTimeout')
}, 0)

fetchData()

In the example above, the code in the Promise will be scheduled in the Microtask queue, but since that action requires the network, it will only be resolved after the data is received. In this example, we’ll see this output:

Hi!
Hi from setTimeout!
Hi from fetch

We also need to mention that the timing of callbacks and Promises can vary significantly depending on the environment (browser or Node.js).

Promise Methods

Promise.all(iterable)

It takes an array of Promises and returns a Promise that either fulfills when all of the Promises in the iterable argument have been fulfilled or rejects as soon as one of the Promises rejects. If the returned Promise fulfills, it’s fulfilled with an array of the values from the fulfilled Promises in the same order as defined in the array argument. If the returned Promise rejects, it is rejected with the reason from the first Promise in the array that got rejected. This method can be useful for aggregating results of multiple Promises.

The biggest confusion about Promise.all is that Promises passed in the iterable are executed concurrently. Promise.all doesn’t provide parallelism! The function passed in the Promise constructor is executed immediately and Promise is resolved in the microtask queue. Microtasks are always executed in sequence.

This method is useful when we want to wait for multiple Promises to resolve (or reject) without manually chaining them. The most common use case is mapping through an array and returning a Promise for every element:

const results = await Promise.all(

 items.map(item => generateResultFromItem(item))

)

The first rejection of a Promise will cause Promise.all() to reject, but other constituent Promises will still be executing. This can be harmful as we will be using resources for generating results that won’t be used.

const util = require('util')
const sleep = util.promisify(setTimeout)

Promise.all([
  sleep(1000).then(() => console.log('b')),
  Promise.reject('a')
]).catch((err) => console.log(err))

In the example above, we’re passing two Promises in Promise.all(). The first one is waiting one second and then logging letter b in the console. The second one is rejected with the letter a. Since the second one is rejected, we would expect to see only a in the console, but you’ll see **a **and b. That’s because you can’t cancel the Promise. Every scheduled Promise will be executed and Promise.all just helps us to ignore the result if one of the Promises in the iterable is rejected, and gives us a rejected Promise as a result.

Promise.race(iterable)

It takes an array of Promises and executes them in the same way as Promise.all, the difference being it returns a Promise that fulfills or rejects as soon as one of the Promises in the iterable fulfills or rejects, with the value or reason from that Promise. As an example, Promise.race can be used for building a timeout functionality, where the first Promise will be an HTTP request to some service, and a second one will be a timeout function. If the second one fails first, the resulting Promise from Promise.race() will be rejected and the data from the first Promise won’t be available. The rejection of one Promise from the iterable won’t cancel others, they will be still be executed, as in the Promise.all method case.

const fetch = require('node-fetch') // only when running in Node.js

const getUserRepos = () =>
 fetch('https://api.github.com/users/nearform/repos')

const timeout = delay =>
  new Promise((resolve, reject) => {
    setTimeout(() => reject(new Error('request timeout')), delay)
  })

Promise.race([getUserRepos(), timeout(300)])
  .then(repos => console.log(repos))
  .catch(e => console.error(e))

Promise.reject(reason)

Returns a Promise object that is rejected with the given reason as an argument. It is mainly used to throw an error in the Promise chain.

Promise.resolve(value)

Returns a Promise that is resolved with the given value as an argument. It is mainly used to cast a value into the Promise, some object or array, so we can chain it later with other async code.

Async/Await

Async/await semantics were added in ECMAScript 2017, allowing programmers to deal with Promises in a more intuitive way. The word “async” before a function means one simple thing: a function always returns a Promise. If the code has returned in it, then JavaScript automatically wraps it into a resolved Promise with that value. The keyword await, which can only occur inside an async function, makes JavaScript wait until the Promise has been settled and returns its result.

Below is a function waiting on a Promise that is resolved after one second using async/await keywords:

let promise = new Promise((resolve, reject) => {
  setTimeout(() => resolve("done!"), 1000)
})

async function f() {
  let result = await promise // wait till the Promise resolves
  alert(result) // "done!"
}

That’s all for Part 1! Tune in on Monday when we’ll discuss common mistakes with promises.

Originally published by Ivan Jovanovic at https://dzone.com

Learn more

☞ The Complete JavaScript Course 2019: Build Real Projects!

☞ JavaScript in Action - bird flying game fun with the DOM

☞ JavaScript Car Driving Game from scratch with source code

☞ Advanced JavaScript Concepts

☞ Selenium WebDriver - JavaScript nodeJS webdriver IO & more!

☞ Complete JavaScript Course For Beginners to Master - 2019

☞ The Modern JavaScript Bootcamp (2019)

JavaScript Tutorial: if-else Statement in JavaScript

JavaScript Tutorial: if-else Statement in JavaScript

This JavaScript tutorial is a step by step guide on JavaScript If Else Statements. Learn how to use If Else in javascript and also JavaScript If Else Statements. if-else Statement in JavaScript. JavaScript's conditional statements: if; if-else; nested-if; if-else-if. These statements allow you to control the flow of your program's execution based upon conditions known only during run time.

Decision Making in programming is similar to decision making in real life. In programming also we face some situations where we want a certain block of code to be executed when some condition is fulfilled.
A programming language uses control statements to control the flow of execution of the program based on certain conditions. These are used to cause the flow of execution to advance and branch based on changes to the state of a program.

JavaScript’s conditional statements:

  • if
  • if-else
  • nested-if
  • if-else-if

These statements allow you to control the flow of your program’s execution based upon conditions known only during run time.

  • if: if statement is the most simple decision making statement. It is used to decide whether a certain statement or block of statements will be executed or not i.e if a certain condition is true then a block of statement is executed otherwise not.
    Syntax:
if(condition) 
{
   // Statements to execute if
   // condition is true
}

Here, condition after evaluation will be either true or false. if statement accepts boolean values – if the value is true then it will execute the block of statements under it.
If we do not provide the curly braces ‘{‘ and ‘}’ after if( condition ) then by default if statement will consider the immediate one statement to be inside its block. For example,

if(condition)
   statement1;
   statement2;

// Here if the condition is true, if block 
// will consider only statement1 to be inside 
// its block.

Flow chart:

Example:

<script type = "text/javaScript"> 

// JavaScript program to illustrate If statement 

var i = 10; 

if (i > 15) 
document.write("10 is less than 15"); 

// This statement will be executed 
// as if considers one statement by default 
document.write("I am Not in if"); 

< /script> 

Output:

I am Not in if
  • if-else: The if statement alone tells us that if a condition is true it will execute a block of statements and if the condition is false it won’t. But what if we want to do something else if the condition is false. Here comes the else statement. We can use the else statement with if statement to execute a block of code when the condition is false.
    Syntax:
if (condition)
{
    // Executes this block if
    // condition is true
}
else
{
    // Executes this block if
    // condition is false
}


Example:

<script type = "text/javaScript"> 

// JavaScript program to illustrate If-else statement 

var i = 10; 

if (i < 15) 
document.write("10 is less than 15"); 
else
document.write("I am Not in if"); 

< /script> 

Output:

i is smaller than 15
  • nested-if A nested if is an if statement that is the target of another if or else. Nested if statements means an if statement inside an if statement. Yes, JavaScript allows us to nest if statements within if statements. i.e, we can place an if statement inside another if statement.
    Syntax:
if (condition1) 
{
   // Executes when condition1 is true
   if (condition2) 
   {
      // Executes when condition2 is true
   }
}

Example:

<script type = "text/javaScript"> 

// JavaScript program to illustrate nested-if statement 

var i = 10; 

if (i == 10) { 

// First if statement 
if (i < 15) 
	document.write("i is smaller than 15"); 

// Nested - if statement 
// Will only be executed if statement above 
// it is true 
if (i < 12) 
	document.write("i is smaller than 12 too"); 
else
	document.write("i is greater than 15"); 
} 
< /script> 

Output:

i is smaller than 15
i is smaller than 12 too
  • if-else-if ladder Here, a user can decide among multiple options.The if statements are executed from the top down. As soon as one of the conditions controlling the if is true, the statement associated with that if is executed, and the rest of the ladder is bypassed. If none of the conditions is true, then the final else statement will be executed.
if (condition)
    statement;
else if (condition)
    statement;
.
.
else
    statement;


Example:

<script type = "text/javaScript"> 
// JavaScript program to illustrate nested-if statement 

var i = 20; 

if (i == 10) 
document.wrte("i is 10"); 
else if (i == 15) 
document.wrte("i is 15"); 
else if (i == 20) 
document.wrte("i is 20"); 
else
document.wrte("i is not present"); 
< /script> 

Output:

i is 20

How to Retrieve full Profile of LinkedIn User using Javascript

How to Retrieve full Profile of LinkedIn User using Javascript

I am trying to retrieve the full profile (especially job history and educational qualifications) of a linkedin user via the Javascript (Fetch LinkedIn Data Using JavaScript)

Here we are fetching LinkedIn data like Username, Email and other fields using JavaScript SDK.

Here we have 2 workarounds.

  1. Configuration of linkedIn developer api
  2. Javascript Code to fetch records

Configuration of linkedIn developer api

In order to fetch records, first we need to create developer api in linkedin which will act as token/identity while fetching data from other linkedin accounts.

So to create api, navigate to https://linkedin.com/developer/apps and click on 'Create Application'.

After navigating, fill in details like name, description and other required fields and then submit.

As we submit, it will create Client ID and Client Secret shown below, which we will be using in our code while communicating to fetch records from other LinkedIn account.

Note: We need to provide localhost Url here under Oauth 2.0. I am using my localhost, but you can probably use other production URLs under Oauth 2.0 where your app is configured. It will make your api  consider the Url as trusted which fetching records.

Javascript Code to fetch records

For getting user details like first name, last name,User image can be written as,

<script type="text/javascript" src="https://platform.linkedin.com/in.js">  
    api_key: XXXXXXX //Client ID  
    onLoad: OnLinkedInFrameworkLoad //Method that will be called on page load  
    authorize: true  
</script>  
<script type="text/javascript">  
    function OnLinkedInFrameworkLoad() {  
        IN.Event.on(IN, "auth", OnLinkedInAuth);  
    }  
  
    function OnLinkedInAuth() {  
        IN.API.Profile("me").result(ShowProfileData);  
    }  
  
    function ShowProfileData(profiles) {  
        var member = profiles.values[0];  
        var id = member.id;  
        var firstName = member.firstName;  
        var lastName = member.lastName;  
        var photo = member.pictureUrl;  
        var headline = member.headline;  
        //use information captured above  
        var stringToBind = "<p>First Name: " + firstName + " <p/><p> Last Name: " + lastName + "<p/><p>User ID: " + id + " and Head Line Provided: " + headline + "<p/>"  
        document.getElementById('profiles').innerHTML = stringToBind;  
    }  
</script>    

Kindly note we need to include 'https://platform.linkedin.com/in.js' as src under script type as it will act on this Javascript SDK provided by Linkedin.

In the same way we can also fetch records of any organization with the companyid as keyword.

<head>  
    <script type="text/javascript" src="https://platform.linkedin.com/in.js">  
        api_key: XXXXXXX ////Client ID  
        onLoad: onLinkedInLoad  
        authorize: true  
    </script>  
</head>  
  
<body>  
    <div id="displayUpdates"></div>  
    <script type="text/javascript">  
        function onLinkedInLoad() {  
            IN.Event.on(IN, "auth", onLinkedInAuth);  
            console.log("On auth");  
        }  
  
        function onLinkedInAuth() {  
            var cpnyID = XXXXX; //the Company ID for which we want updates  
            IN.API.Raw("/companies/" + cpnyID + "/updates?event-type=status-update&start=0&count=10&format=json").result(displayCompanyUpdates);  
            console.log("After auth");  
        }  
  
        function displayCompanyUpdates(result) {  
            var div = document.getElementById("displayUpdates");  
            var el = "<ul>";  
            var resValues = result.values;  
            for (var i in resValues) {  
                var share = resValues[i].updateContent.companyStatusUpdate.share;  
                var isContent = share.content;  
                var isTitled = isContent,  
                    isLinked = isContent,  
                    isDescription = isContent,  
                    isThumbnail = isContent,  
                    isComment = isContent;  
                if (isTitled) {  
                    var title = isContent.title;  
                } else {  
                    var title = "News headline";  
                }  
                var comment = share.comment;  
                if (isLinked) {  
                    var link = isContent.shortenedUrl;  
                } else {  
                    var link = "#";  
                }  
                if (isDescription) {  
                    var description = isContent.description;  
                } else {  
                    var description = "No description";  
                }  
                /* 
                if (isThumbnailz) { 
                var thumbnailUrl = isContent.thumbnailUrl; 
                } else { 
                var thumbnailUrl = "http://placehold.it/60x60"; 
                } 
                */  
                if (share) {  
                    var content = "<a target='_blank' href=" + link + ">" + comment + "</a><br>";  
                    //el += "<li><img src='" + thumbnailUrl + "' alt=''>" + content + "</li>";  
                    el += "<li><div>" + content + "</div></li>";  
                }  
                console.log(share);  
            }  
            el += "</ul>";  
            document.getElementById("displayUpdates").innerHTML = el;  
        }  
    </script>  
</body>  

We can get multiple metadata while fetching records for any any organization. We can get company updates as shown below.

Conclusion

We can also fetch any company specific data like company job updates/post, total likes, comments, and number of views along with a lot of metadata we can fetch which I have shown below.

Thank you for reading !

7 Best Javascript Iframe Libraries

7 Best Javascript Iframe Libraries

Iframes let you build user experiences into embeddable ‘cross-domain components’, which let users interact with other sites without being redirected. I have compiled 7 best Javascript iframe libraries.

Iframes let you build user experiences into embeddable ‘cross-domain components’, which let users interact with other sites without being redirected. I have compiled 7 best Javascript iframe libraries.

1. Zoid

A cross-domain component toolkit, supporting:

  • Render an iframe or popup on a different domain, and pass down props, including objects and functions
  • Call callbacks natively from the child window without worrying about post-messaging or cross-domain restrictions
  • Create and expose components to share functionality from your site to others!
  • Render your component directly as a React, Vue or Angular component!
    It's 'data-down, actions up' style components, but 100% cross-domain using iframes and popups!

Download


2. Postmate

Postmate is a promise-based API built on postMessage. It allows a parent page to speak with a child iFrame across origins with minimal effort.

Download


3. Iframe Resizer

Keep same and cross domain iFrames sized to their content with support for window/content resizing, in page links, nesting and multiple iFrames

Demo

Download


4. Iframely

Embed proxy. Supports over 1800 domains via custom parsers, oEmbed, Twitter Cards and Open Graph

Demo

Download


5. React Frame component

This component allows you to encapsulate your entire React application or per component in an iFrame.

Demo

Download


6. Seamless.js

A seamless iframe makes it so that visitors are unable to distinguish between content within the iframe and content beside the iframe. Seamless.js is a JavaScript library (with no dependencies) that makes working with iframes easy by doing all the seamless stuff for you automatically.

Demo

Download


7. Porthole

A proxy to safely communicate to cross-domain iframes in javascript

Demo

Download


Thank for read!