简体   繁体   中英

Asynchronous behavior and callbacks in javascript

I was hopping around various websites but couldn't understand how callbacks make javascript asynchronous. To my understanding callbacks are any functions that are called inside one another function. It is just another function call. How does javascript know which functions to execute asynchronously and how it handles under the hood?

Sample Code 1

function A(x){
//...code for func A;
}

function B(y){
//...code for func B;
A(2);  // 2 for example
}

Sample Code 2:

function A(x){
//...code for func A;
}

function B(y,A){
//...code for func B;
A(2);  // 2 for example
}

Kindly explain how javascript differentiates between these two pieces codes?

I was hopping around various websites but couldn't understand how callbacks make javascript asynchronous.

They do not. The code you posted, by itself, isn't asynchronous. Callbacks are not an asynchronous pattern on their own (as an example look at Array.prototype.forEach ) but they are used as one way to handle asynchronous behavior.

To my understanding callbacks are any functions that are called inside one another function. It is just another function call.

Basically, except that they are also passed as arguments. When we say a callback in javascript, we usually mean functions that are passed down from one function to another and that call back the initial function, hence the name. In general however, a callback is just a piece of executable code, that is passed as an argument to other code.


The main difference between the two samples you provided here is how they obtain access to each other , not whether they are asynchronous or synchronous.

Both samples contain synchronous code but only one of them contains a callback:

  • Sample 1: function B obtains access to A via its global scope. not callback
  • Sample 2: function B obtains access to A via its arguments: callback

For sample 1, no matter how you call B(y) , since it always invokes A internally, it doesn't callback anything, it just calls another function.

For sample 2, you can call B(y, A) or B(y, C) with another function C(){} and it will call back whichever function you passed into it.

Perhaps it would be less confusing if you renamed the functions like this:

Sample Code 1

function A(x){
  //...code for func A;
}

function B(y){
  //...code for func B;
  A(2);  // calls above A()
}

Sample Code 2:

function A(x){
  //...code for func A;
}

function B(y, callback){
  //...code for func B;
  callback(2);  // calls whichever callback you pass in
}

Demonstration examples

 // EXAMPLE 1 function A1() { console.log('A1 is called'); } function B1() { console.log('B1 is called'); A1(2); // calls above A() } B1(); // Output: // B1 is called // A1 is called B1('whatever'); // Output: // B1 is called // A1 is called // EXAMPLE 2 function A2() { console.log('A2 is called'); } function B2(callback) { console.log('B2 is called'); callback(); // calls whichever callback you pass in } // We can callback to any function (but not no function) B2(A1); // Output: // B2 is called // A1 is called B2(A2); // Output: // B2 is called // A2 is called B2(); // Output: // B2 is called // Uncaught TypeError: callback is not a function (because we didn't pass anything as the callback)

Sample Code 1 as async

Now let's demonstrate some asynchronous behavior with a common tool, the setTimeout function. I will use sample code 1 because it doesn't contain any callback code, to also show how callbacks tie into async behavior.

function A(x){
  //...code for func A;
}

function B(y){
  //...code for func B;
  setTimeout(A, 3000); // call A after 3 seconds
}

B();

In the code above, function A is passed as a callback to function setTimeout . That means that setTimeout definition would conceptually look something like:

function setTimeout(callback, duration) {
 // call callback after duration milliseconds
}

What happens when you execute the above code is that the lexical parser first hoists the functions to the top of the code . Then the invocation of B() happens, followed by all synchronous code afterwords because JS is single-threaded. This means that A cannot be executed until the thread that called setTimeout() has terminated.

Only when all synchronous code is finished and 3 seconds have passed will you get invocation of A() .

In general, anytime you write some code to react when data from the server is received or when the user clicks the mouse, that code is asynchronous. It gets executed when something happens .

As @Pointy pointed out in the comments, this asynchronous behavior isn't a direct feature of JavaScript on its own. It usually comes from interaction with the system JS is running in and the events that system sends (user interacting with the browser or the operating system interacting with something like NodeJS)

Asynchronous behavior of Javascript

 <script> var message = ''; function writeToDocument( string ) { window.message += '<br/>'+string; document.write(window.message); } function A() { var string = 'A is Called'; setTimeout( function(){writeToDocument(string)},3000); } function B() { writeToDocument('B is Called'); } A(); //We are calling A first; B(); </script>

OUTPUT

B is Called
A is Called

even though we called A first, B gets called first, Javascript is Asynchronous

Synchronous behavior of PHP

<?php

function writeToDocument( $string )
{
    echo '<br/>'.$string; 
}

function A()
{
    sleep(3000);
    writeToDocument('A is Called');
}

function B()
{
    writeToDocument('B is Called');
}

A();
B();

OUTPUT

A is Called
B is Called

B will not be called unless A is finished executing, PHP is Synchronous

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM