我是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);
});
});
答案 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)
});
};
答案 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的更多信息。