Geo*_*ker 26 javascript asynchronous callback asynccallback
我一直在努力解决这个问题.我是Javascript的新手,并且一直认为我写的代码已经异步运行了.这是一个通用的例子:
我在函数a中运行了一些代码.函数A然后调用函数B,函数B需要将变量返回给A,因此A可以在以后的操作中使用它.看来,当A调用B时,它仍然继续运行自己的代码,而不是等待其返回值被阻塞,并且B不够快,使得A最终到达需要使用返回的点值,我得到一个未定义的变量类型错误.
我解决这个问题的方法是函数A调用函数B然后调用一个函数C,它将执行A将使用返回值执行的后续操作....我有点通过调用序列化我的代码而不是返回......虽然很麻烦......
以下是在实际代码中发生的示例:
function initialize() {
//Geocode Address to obtin Lat and Long coordinates for the starting point of our map
geocoder = new google.maps.Geocoder();
var results = geocode(geocoder);
makeMap(results[0].geometry.location.lat(), results[0].geometry.location.lng());
}
function geocode(geocoder) {
//do geocoding here...
var address = "3630 University Street, Montreal, QC, Canada";
geocoder.geocode({ 'address': address }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
return results;
}
else {
alert("Geocode was not successful for the following reason: " + status);
}
});
}
function makeMap(lat, long) {
// alert(lat); for debuging
var mapOptions = {
center: new google.maps.LatLng(lat, long),
zoom: 17,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map_canvas"),
mapOptions);
}
Run Code Online (Sandbox Code Playgroud)
注意:我的html中的body onload ="initialize()"会调用initialize.
所以问题是makeMap需要Geocode函数获得的纬度和经度值,但是在控制台中我得到一个错误,说结果是未定义的.到底是怎么回事?我来自Java,所以我对JS中数据流的发生方式感到有些困惑!这将是未来的宝贵经验!
关于一个问题:我应该如何在外部脚本之间拆分我的功能?什么是好习惯?我的所有功能都应该塞进一个外部.js文件中,还是应该将功能组合在一起?
jnc*_*ton 35
您似乎对问题有了很好的理解,但听起来您并不熟悉解决问题的方法.解决此问题的最常见方法是使用回调.这基本上是等待返回值的异步方式.以下是您在案例中如何使用它:
function initialize() {
//Geocode Address to obtin Lat and Long coordinates for the starting point of our map
geocoder = new google.maps.Geocoder();
geocode(geocoder, function(results) {
// This function gets called by the geocode function on success
makeMap(results[0].geometry.location.lat(), results[0].geometry.location.lng());
});
}
function geocode(geocoder, callback) {
//do geocoding here...
var address = "3630 University Street, Montreal, QC, Canada";
geocoder.geocode({ 'address': address }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
// Call the callback function instead of returning
callback(results);
} else {
alert("Geocode was not successful for the following reason: " + status);
}
});
}
...
Run Code Online (Sandbox Code Playgroud)
T.J*_*der 12
我...的印象是我写的代码一直在异步运行.
是的,它确实.您的geocode
功能无法将调用结果返回给Google API,因为该功能会在Google调用完成之前返回.见下面的注释:
function geocode(geocoder) {
//do geocoding here...
var address = "3630 University Street, Montreal, QC, Canada";
geocoder.geocode({ 'address': address }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
// +---------- This doesn't return anything from your
// v geocode function, it returns a value from the callback
return results;
}
else {
alert("Geocode was not successful for the following reason: " + status);
}
});
}
Run Code Online (Sandbox Code Playgroud)
相反,您必须对geocode
函数进行编码,以便它接受一个回调,当它有结果时它将调用它.例如:
// Added a callback arg ---v
function geocode(geocoder, callback) {
//do geocoding here...
var address = "3630 University Street, Montreal, QC, Canada";
geocoder.geocode({ 'address': address }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
// v---------- Call the callback
callback(results);
}
else {
alert("Geocode was not successful for the following reason: " + status);
callback(null); // <--- Call the callback with a flag value
// saying there was an error
}
});
}
Run Code Online (Sandbox Code Playgroud)
然后,而不是像这样使用它:
var results = geocode(someArgHere);
if (results) {
doSomething(results);
}
else {
doSomethingElse();
}
Run Code Online (Sandbox Code Playgroud)
你这样称呼它:
geocode(someArgHere, function() {
if (results) {
doSomething(results);
}
else {
doSomethingElse();
}
});
Run Code Online (Sandbox Code Playgroud)
例如,你完全异步.
归档时间: |
|
查看次数: |
32511 次 |
最近记录: |