将Async功能作为Sync运行

时间:2018-04-21 17:58:12

标签: javascript angularjs mongodb express

我是javascript编程的新手,我试图理解异步过程。我已经启动了一个项目,我想知道如何执行下面的代码作为同步。我看过很多教程,但是大部分内容都很肤浅......

代码很简单,它调用谷歌地图api传递地址并返回纬度和经度。之后,它应该通过url调用服务器传递lat lng并返回指定位置附近的所有位置。

客户端:

$scope.findLocations = function () {

    var dist = 0.1;

    //execute this
    getLatLong();

    //before this
    $http.get('/api/locations/findByLocation/'+$scope.form.lng+'/'+$scope.form.lat+'/'+dist)
    .success(function(data) {
        $scope.locations = data;
        $scope.form = {};
        console.log("locations: ", data);
    })
    .error(function(data) {
        console.log('Error: ' + data);
    });


};


var getLatLong = function() {

    var geo = new google.maps.Geocoder;

    var address = $scope.form.adress;

    console.log(address);

    geo.geocode({'address':address},function(results, status){
        if (status == google.maps.GeocoderStatus.OK) {
            console.log("Status geocoder OK");
            $scope.form.lat = results[0].geometry.location.lat();
            $scope.form.lng = results[0].geometry.location.lng();

            var latlng = new google.maps.LatLng($scope.form.lat,$scope.form.lng);

            var mapProp = {
                    center:latlng,
                    zoom:18,
                    mapTypeId:google.maps.MapTypeId.ROADMAP,
                    mapTypeControl: false
            };

            var map=new google.maps.Map(document.getElementById("map"),mapProp);
            var marker = new google.maps.Marker({
                    position: latlng,
                    map: map,
                    title:name
            });

            } else {
            alert(status);
        }

      });

};

服务器:

router.get('/api/locations/findByLocation/:lng/:lat/:dist', function(req, res){

var coords = [];
coords[0] = req.params.lng;
coords[1] = req.params.lat;

Location.find({
    loc: {
        $near: coords,
        $maxDistance: req.params.dist
    }
}).limit(30).exec(function(err, locations){

    if(err){
        res.json(err);
        console.log(err);
    }

    res.json(locations);
});

});

4 个答案:

答案 0 :(得分:1)

为此使用JS Promise

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

$scope.findLocations = function() {

    var dist = 0.1;

    //execute this
    getLatLong().then(function(resolve) {
        //before this
        $http.get('/api/locations/findByLocation/' + $scope.form.lng + '/' + $scope.form.lat + '/' + dist)
            .success(function(data) {
                $scope.locations = data;
                $scope.form = {};
                console.log("locations: ", data);
            })
            .error(function(data) {
                console.log('Error: ' + data);
            });
    }, function(error) {
        alert("You got some error!");
    });

};



var getLatLong = function() {

    var geo = new google.maps.Geocoder;

    var address = $scope.form.adress;

    console.log(address);

    return new Promise(function(resolve, reject) {

        geo.geocode({
            'address': address
        }, function(results, status) {
            if (status == google.maps.GeocoderStatus.OK) {
                console.log("Status geocoder OK");
                $scope.form.lat = results[0].geometry.location.lat();
                $scope.form.lng = results[0].geometry.location.lng();

                var latlng = new google.maps.LatLng($scope.form.lat, $scope.form.lng);

                var mapProp = {
                    center: latlng,
                    zoom: 18,
                    mapTypeId: google.maps.MapTypeId.ROADMAP,
                    mapTypeControl: false
                };

                var map = new google.maps.Map(document.getElementById("map"), mapProp);
                var marker = new google.maps.Marker({
                    position: latlng,
                    map: map,
                    title: name
                });

                resolve(200);
            } else {
                reject(status);
            }

        });
    });
};

答案 1 :(得分:1)

你应该检查Promise如何在javascript中工作。这里的例子:

var getLastLong = function() {
    return $q(function(resolve, reject) {

        var geo = new google.maps.Geocoder;

        var address = $scope.form.adress;

        console.log(address);

        geo.geocode({ 'address': address }, function(results, status) {
            if (status == google.maps.GeocoderStatus.OK) {
                console.log("Status geocoder OK");
                $scope.form.lat = results[0].geometry.location.lat();
                $scope.form.lng = results[0].geometry.location.lng();

                var latlng = new google.maps.LatLng($scope.form.lat, $scope.form.lng);

                var mapProp = {
                    center: latlng,
                    zoom: 18,
                    mapTypeId: google.maps.MapTypeId.ROADMAP,
                    mapTypeControl: false
                };

                var map = new google.maps.Map(document.getElementById("map"), mapProp);
                var marker = new google.maps.Marker({
                    position: latlng,
                    map: map,
                    title: name
                });
                // say success with marker payload.
                resolve(marker);

            } else {
                // Say error with marker payload.
                reject(status);
            }
        });
    });
}

$scope.findLocations = function () {

    var dist = 0.1;
    getLatLong()
    .then(function(marker) {
        // Here you receive marker defer by promise, this code will be execute when "resolve" is call on your getLatLong() method
        $http.get('/api/locations/findByLocation/'+$scope.form.lng+'/'+$scope.form.lat+'/'+dist)
        .success(function(data) {
            $scope.locations = data;
            $scope.form = {};
            console.log("locations: ", data);
        })
        .error(function(data) {
            console.log('Error: ' + data);
        });

    })
    .catch(function(error) {
        console.log(error)
    });
};

Official promise api

angular 1 implementation of promise

答案 2 :(得分:1)

我喜欢处理的方式"这个"那么"这个"那么"那" javascript中的链是使用promises。这是一个学习曲线,但在处理异步api调用时会产生简单的可维护代码。首先在您的angular?服务中包含$ q依赖项? (从你的电话的角度成分内部发布的代码中不清楚)。

这就是你的例子中的样子:

 getLatLong()
 .then(function(longLat) {
      // process answer here
      $http.get('/api/locations/findByLocation/'+$scope.f...
      ...
      return something;
 })
 .then(function(something) {
      // so something more
 });

答案 3 :(得分:1)

调用geo.geocode({'address':address},function(results, status){...}是异步调用。这意味着它将调用Google Maps API,代码的下一行将在不等待答案的情况下执行。

此调用的第二个参数是回调:function(results, status){...}。此回调函数仅在异步调用完成其进程时执行。

为了在Google Maps API返回后拨打您的服务器,您需要在回调中对此调用进行编码,如下所示:

geo.geocode({'address':address},function(results, status){
    if (status == google.maps.GeocoderStatus.OK) {
        console.log("Status geocoder OK");
        $scope.form.lat = results[0].geometry.location.lat();
        $scope.form.lng = results[0].geometry.location.lng();

        var latlng = new google.maps.LatLng($scope.form.lat,$scope.form.lng);

        var mapProp = {
                center:latlng,
                zoom:18,
                mapTypeId:google.maps.MapTypeId.ROADMAP,
                mapTypeControl: false
        };

        var map=new google.maps.Map(document.getElementById("map"),mapProp);
        var marker = new google.maps.Marker({
                position: latlng,
                map: map,
                title:name
        });

        //call the server at this point...
        //http.request(options, function(response){...})

    } else {
        alert(status);
    }

  });

您可以找到有关http call here的更多信息。