Returning data from deferred?

I have a class that uses the google places service. The user can enter the address and Google will return the information to him.

Later, I want to find the lat and lng coordinates at that location, so I have this method that cleans up the google location service to get the coordinates.

I am returning a deferred one as it may take a while.

p.getLatLong = function() {

    var dfd = $.Deferred();

        this.placesService.getDetails({
            reference: this.pacReference
        }, function(details, status){
            if(details){
                dfd.resolve({'lat' : details.geometry.location.lat(), 'lng' : details.geometry.location.lng()});
            }
            else{
                dfd.reject();
            }
        })
    }

    return dfd;
};

      

I want to be able to access the above method and just return coordinates or null (if dfd is rejected), but the method returns deferred.

How can I just return the result of dfd and not dfd itself?

I do not want to call:

this.geo.getLatLng().done(function(data){console.log(data})

      

But something like this:

console.log(this.geo.getLatLng());

      

+3


source to share


2 answers


I understand, although promises exist for some reason, the reason here is the asynchronous nature of the data request.



There is a way I thought it was good before I understood the purpose of promises. You can return the data link "be filled", but when can you use it? Are you planning to poll the state of the object ...? Hope not, stick to promises seriously, you will avoid a lot of trouble for a little profit from a few keystrokes.

0


source


Deferred objects are meant to keep the thread running while long-running operations run in the background. They serve a specific purpose and shouldn't work the way you describe by design.

Remember JavaScript is single threaded. This means that if you suspend a thread waiting for a long operation to complete, the entire page / UI will be frozen as well.


In this warning, you could accomplish what you want by including all of this in your closure with a loop that checks to see if the process exited.



Note that this is dangerous, freezes the page and should be avoided. He's only here for academic reasons.

var getGetLatLng = (function () {
    var running = false;

    return function () {
        var latlng;

        //While we haven't instructed the loop to break.
        while (!breakLoop) {
            //If we haven't instructed the API call to execute in this iteration of the loop.
            if (!running) {
                //On next iteration, tell it we are already running, to prevent multiple requests being fired.
                running = true;

                //Your logic here for getLatLng
                this.geo.getLatLng()
                    //When it completes successfully, set latlng
                    .done(function (data) {
                        latlng = data;
                    })
                    //always break the loop when HTTP completes.
                    .always(function () {
                        breakLoop = true;
                    });
            }
        }

        //Return latlng - it could be undefined if there was an error.
        return latlng;
    };
})();

      

You can wrap this same structure around your original body p.getLatLng

. Again, I don't recommend it.

0


source







All Articles