Confusion with Javascript callbacks - seeking clarity

I am having difficulty grasping the concept of callback functions. I know that they are functions passed as parameters to other functions. My assumption was that when a function is passed as a parameter, it would be recognized as a callback function and executed at the end, after everything else has been processed.

To test this theory, I wrote the following code snippet:

newFunction = (x,y,z, callback) => {
    callback();
    let sum = x + y + z;
    console.log(sum);
}

newerFunction = () => {
    console.log("This is the callback function");
}

newFunction(2,3,4,newerFunction)

If my understanding was correct, I should have seen the sum logged first, followed by the callback function printing "This is the callback function."

Surprisingly, the opposite happened. The callback function was called first, then the sum was printed. Although the order of execution in the newFunction suggests this, if the callback were truly executed last, the sum should have been logged before.

I realize that callbacks can be synchronous, but my understanding of their concept seems incomplete and inaccurate.

Please provide assistance.

I used to believe I had a good grasp on the topic, but upon revisiting it, I find myself struggling to comprehend it.

Thank you for your help.

Answer №1

My initial assumption was that when passing a function as a parameter to the interpreter, it would be recognized as a callback function and executed at the end of the process.

However, this is not the case.

Callback functions must be explicitly invoked by the function they are supplied to. The JavaScript engine cannot determine what arguments should be passed to the callback or how to handle its return value.

Callback functions run only when called.

Consider Array.prototype.forEach() as an example.

The purpose of this function is to execute the callback function for each element in an array. It would serve no purpose if it ran only once at the conclusion of execution.

const array = [5, 4, 3, 2, 1];
const callback = member => console.log(member);
array.forEach(callback);

Answer №2

When a function X is passed as an argument to another function Y, it is referred to as a callback. We can anticipate that function Y will invoke function X at a specific moment. This invocation could occur immediately in the case of a synchronous callback (similar to the example provided), or it may be delayed to a later point in time for an asynchronous callback.

The timing of when a callback function is executed is not determined solely by being designated as a callback; instead, it is dictated by the caller of the function. The only certainty is that the callback function will be called, hence its name.

Answer №3

  1. Both newFunction and newerFunction are functions that operate synchronously. In order to create a function that operates asynchronously, you must use the async keyword or return a promise from within your function.
  2. Because these functions are synchronous, the code is executed in a sequential manner. JavaScript is inherently a synchronous language, so each line of code is processed one after the other. When encountering the callback(); statement, it is immediately executed since the function passed as a parameter is also synchronous. This means that the code within the callback function is executed entirely before moving on to the next part of the newFunction.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Tips on effectively centering a wide div

After much experimentation, this is what I came up with: (function(d, s, id) { var js, fjs = d.getElementsByTagName(s)[0]; if (d.getElementById(id)) return; js = d.createElement(s); js.id = id; js.src = "//connect.facebook.net/en ...

Looking for a solution to my issue - my for loop is looping more times than it should

I am designing a confirm dialog using jQuery and Bootstrap. When the user clicks on 'Yes' or 'No', it should trigger an action, such as drawing two squares each time. The first time I click either button, it draws 2 squares. However, wi ...

Tips for positioning divs on top of an image with Twitter Bootstrap

I'm having an issue with displaying an image and dividing it using bootstrap div columns. The problem is that the image is overlapping the divs, making it impossible to click or attach jQuery events to it. Here is the code I am currently using: #view ...

In Node JS, the variable ID is unable to be accessed outside of the Mongoose

When working with a Mongoose query, I encountered an error where I am trying to assign two different values to the same variable based on the query result. However, I keep getting this error: events.js:187 throw er; // Unhandled 'error' ev ...

react-responsive-carousel: setting a specific height for thumbnail images

After setting a fixed height for the image, I noticed that the same height is also being applied to the thumbnails. How can I avoid this issue? <Carousel width="600px" dynamicHeight={false}> {data?.book?.images.map((image, i) => ( ...

Changing the background color with a switch function in ReactJS

After clicking a link, a view is rendered based on the "id" from a JSON. To enhance the user experience, I want to add a background color when a particular view renders and also toggle the style. This code snippet illustrates how the crawl is displaye ...

Error: Unable to cast value "undefined" to an ObjectId for the "_id" field in the "User" model

Whenever a user logs into their account, I am trying to retrieve their data on the login screen. The login functionality itself works perfectly, but unfortunately, the user data is not displaying. I have tried troubleshooting this issue by making changes i ...

Utilizing AJAX to define the attributes of an object

As a beginner in OOP, I am trying to create an object using an ajax request. My goal is to retrieve 'responseArray' in JSON format and then manipulate it. function address(adres) { this.address_string = adres; var self = this; $.ajax({ typ ...

Storing ng-change event for a checkbox in AngularJS in a valid manner

I have a requirement where I need to handle multiple input checkboxes. The goal is to store the changed checkbox events in an array and then save them when the user submits the changes. <td><input type="checkbox" class="switch" ng-model="each_val ...

Discover the pixel width of a Bootstrap grid row or container using JavaScript

How can I calculate the width of a Bootstrap grid row or container in pixels using JavaScript? I am working with Aurelia for my JavaScript project, but I'm open to solutions in standard JS (no jQuery, please). Looking at the Bootstrap documentation, ...

Tips for designing a multi-level dropdown navbar

I am currently facing an issue with designing a navbar. I am aiming for Multi-Level Dropdowns, but whenever I click on More Services, it automatically closes the main dropdown menu. I have experimented with various approaches, but none of them seem to be ...

Ways to bring GIFs into NextJS

I am currently working on my portfolio website using Nextjs and I would like to incorporate gifs into the site. However, I have been struggling to figure out how to do so. Below is the code that I have been working with: https://i.stack.imgur.com/zjoiD.pn ...

Determine if a file input is linked in React.js Material UI

Currently, I am working with a Material UI <TextField /> component that has a type=file prop to allow file attachments. My goal is to trigger an event when a file is attached to this TextField. However, my search results only provided JQuery soluti ...

Mongoose encountering an issue with undefined properties (specifically 'prototype') and cannot read them

I am currently using Mongoose 7.0.1 on Next JS 13.2.2 and React 18.2.0. After tirelessly searching for a solution to my problem, I am still struggling with connecting to a MongoDB. Every time I try to import mongoose into my project for the connection, an ...

Using Rxjs to handle several requests with various headers

I have a specific requirement where, if hasProcessado == true, 10 additional requests should be made before issuing the final request. If the final request fails, 3 more attempts are needed. Furthermore, when sending the last request, it is essential to n ...

How can I toggle button states within a v-for loop based on input changes in Vue.js?

Within the starting point of my code: https://plnkr.co/LdbVJCuy3oojfyOa2MS7 I am aiming to allow the 'Press' button to be active on each row when there is a change in the input field. To achieve this, I made an addition to the code with: :dis ...

Sending Angular base64 image data to the server

I am encountering an issue while attempting to upload a base64 image from Angular to ExpressJS. The image is being created using html2canvas to generate the base64 representation. When I try to upload the imageData in its current format, I receive an error ...

Encountering issues with gulp-angular-templatecache while processing angular templates through pipelining

I've encountered an issue with gulp-angular-templatecache in my gulpfile. Here's the task causing trouble: gulp.task('templates', function() { return gulp.src(paths.angularTemplates) .pipe(templateCache()) ...

I encountered an issue with Array map when attempting to access the data during a dynamic rendering process

function UserTransactionsComponent1() { const [accounts, setAccounts] = useState(); useEffect(() => { async function fetchData() { const res = await fetch( 'https://proton.api.atomicassets.io/atomicassets/v1/accounts' ...

Is there a way in AngularJS utilizing ui-router to retrieve the ngResource error from $stateChangeError when a request fails in the resolve section of a state?

Check out this plunker where I am facing an issue: http://plnkr.co/edit/vdctsTcMq4nD1xpUl3pu The problem is that the $resource promise is being rejected due to a request failure (404 error). I am aware that I can handle the error within the resolve block ...