简体   繁体   中英

How can I achieve synchronous like behaviour in javascript?

    var routeSearch = new MyGlobal.findRoutes({
        originPlaceId: search.placeInputIds.originPlaceId,
        destinationPlaceId: search.placeInputIds.destinationPlaceId,
        directionsService: search.directionsService,
        directionsDisplay: search.directionsDisplay,
        travel_mode: search.travel_mode
    });

    var routeBoxes = new MyGlobal.routeBoxes({
        radius: parseFloat(document.getElementById("radius").value),
        path: routeSearch.grabFirstRoute(),
        map: search.map
    });

$(document).on('ready', function(){
    MyGlobal.findRoutes = function(request){
        var me = this;
        this.response;
        this.grabFirstRoute = function(){
            return this.response.routes[0].overview_path; // first route from directions service response
        };

        if (!request.originPlaceId || !request.destinationPlaceId) {
            return;
        }
        request.directionsService.route({
            origin: {'placeId': request.originPlaceId},
            destination: {'placeId': request.destinationPlaceId},
            travelMode: request.travel_mode
        }, function(response, status){
            if (status === google.maps.DirectionsStatus.OK) {
                me.response = response;
                request.directionsDisplay.setDirections(response);

            } else {
                window.alert('Directions request failed due to ' + status);
            }
        });
    }
})

I'm not sure how to solve this problem. The MyGlobal.findRoutes constructor doesn't wait for the response to come back from the directionsService before moving on to the MyGlobal.routeBoxes constructor. Is there an easy way to set up my code so that all processes inside of the MyGlobal.findRoutes constructor finish before moving on?

You probably want to use some form of "promises" that add syntactic niceness and make your code easier to reason about. But, sticking to the code you've posted, you can use callbacks (which can become cumbersome in larger apps) to achieve something similar. To demonstrate:

var routeBoxes;

function bootstrapRouteBoxes() {
    routeBoxes = new MyGlobal.routeBoxes({
        // code shortened
    });
}

var routeSearch = new MyGlobal.findRoutes({
    // code shortened
}, function() { bootstrapRouteBoxes(); }); // <-- callback as second arg added

And then allow your findRoutes function to handle that callback:

MyGlobal.findRoutes = function(request, callback){
    // code shortened

    request.directionsService.route({
        // code shortened
    }, function(response, status){
        if (status === google.maps.DirectionsStatus.OK) {
            me.response = response;
            request.directionsDisplay.setDirections(response);
            callback(); // <-- new code
        } else {
            window.alert('Directions request failed due to ' + status);
        }
    });
}

This will not make things synchronous, which is a good thing because otherwise your app might "freeze" while fetching data. It will make sure your routeBoxes aren't constructed until the other service has successfully returned and calls the callback .


As a footnote, for promises you can use various options. Perhaps not the best, but one that's close to what libs you already seem to be using: jQuery promises . If you're using Angular you can also have a look at the $q documentation . But it's a broad topic, and not necessarily directly related to your question. Investigate, and get back to SO if you have a specific question.

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