Search code examples
javascriptgoogle-maps-api-2

Geolocation function parameters behavior


I'm using the google maps api and I've noticed a programmatic behavior that I'm not familiar with in JavaScript:

function success(pos) {
  // ...do something with pos.
}

navigator.geolocation.getCurrentPosition(success);

In the example above it appears as though the success function is passed a 'pos' argument from thin air and the success function isn't invoked inside the getCurrentPosition argument via parentheses. I would expect to see something like this:

function success(pos) {
  //...do something with pos.
}

var pos = //...something;
navigator.geolocation.getCurrentPosition(success(pos));

I just don't understand what is going on here. Where does the argument come from and why isn't the function even invoked with parentheses?


Solution

  • This is a feature you will see often in Javascript. It is commonly called a callback. The lack of parentheses is because Javascript allows you to treat a function like a variable, often referred to as 'first-class functions'. You are passing the success function to the getCurrentPosition method, you are not actually calling the success method.

    When you call navigator.geolocation.getCurrentPosition(success);, you are saying to the getCurrentPosition function that when it has found the position, you would like it to call the function you have provided and pass it the position it got.

    The getCurrentPosition method will be doing something like the following:

    function getCurrentPosition(successCallback) {
        var position = loadFromSomewhereThatMayTakeAWhile();
        successCallback(position);
    }
    

    getCurrentPosition may take many seconds or even minutes to get the current location. You do not want the browser to stop responding while this is happening. Callbacks allow you to say "when this operation has finished, call this other method to do something with the result". The browser can then carry on with other things and only execute your callback when the operation is complete.

    The jQuery ajax function uses this callback style.

    var whenSuccessful = function(data, status, xhr){
        console.log('The data was loaded successfully.')
    };
    
    var whenFailed = function(xhr, status, error){
        console.log('The request failed!')
    };
    
    $.ajax({
      url: "http://myserver.com/some_data.json",
      error: whenFailed, // do this if the request fails for any reason
      success: whenSuccessful // do this if the data was loaded successfully
    })