PDA

View Full Version : سوال: بازگرداندن مقداری از یک تابع



Mohsen6558
دوشنبه 26 مهر 1389, 01:04 صبح
دوستان نزدیک شش هفت ساعت با این مشکل سر و کله زدم
قطعه کد زیر وقتی که اجرا بشه ارتفاع از سطح دریای طول و عرض جغرافیایی که دادم رو روی Alert نشون می ده
مشکل اینجاست که من می خوام اینو Return کنم یعنی اون مقداری که از طریق Alert نشون داده می شه رو Return کنم تا بتونم از تابع استفاده کنم به همین سادگی



<html>
<head>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript">
elevator = new google.maps.ElevationService();
function getElevation(event) {

var locations = [];
var clickedLocation = event;
locations.push(clickedLocation);
var positionalRequest = {
'locations': locations
}
// Initiate the location request
elevator.getElevationForLocations(positionalReques t, function (results, status,locations) {
alert(results[0].elevation);
});
}
</script>
</head>
<body onload="initialize()">
<div id="map_canvas" style="width: 100%; height: 100%; float:left; border: 1px solid black;"></div>
<script>
getElevation (new google.maps.LatLng(38.2567583333333, 48.3149633333333));
</script>
</body>
</html>

mehdi.mousavi
دوشنبه 26 مهر 1389, 17:46 عصر
سلام.
چون اجرای اون تابع زمان میبره، اینجا نمیتونید از return value ی تابع استفاده کنید. در عوض میتونید به این شکل عمل کنید:

<html>
<head>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript">
var elevator = new google.maps.ElevationService();
function getElevation(event, onRequestCompleted) {

var locations = [];
var clickedLocation = event;
locations.push(clickedLocation);
var positionalRequest = {
'locations': locations
}

// Initiate the location request
elevator.getElevationForLocations(positionalReques t, function (results, status, locations) {
if (typeof onRequestCompleted == 'function') {
onRequestCompleted(results[0].elevation);
}
});
}
</script>
</head>
<body onload="initialize()">
<div id="map_canvas" style="width: 100%; height: 100%; float: left; border: 1px solid black;">
</div>
<script type="text/javascript">
getElevation(new google.maps.LatLng(38.2567583333333, 48.3149633333333), function (elevation) {
alert(elevation);
});
</script>
</body>
</html>


دقت کنید کد شما رو چطوری تغییر دادم. اونجاییکه دارم getElevation رو Call میکنم، یه پارامتر دیگه اضافه کردم و یه function بهش پاس کردم تا وقتی پاسخ از سرور دریافت شد اون فراخوانی بشه. سپس در پیاده سازی تابع مربوطه، هنگام مقتضی اون تابع رو با پارامتر مورد نظر فراخوانی کرده ام.

موفق باشید.

پاورقی: لطفا از این پس عناوین مناسبی برای سوالات خود انتخاب کنید.

funpatogh
دوشنبه 26 مهر 1389, 21:17 عصر
این قسمت خطا داره و در خروجی چیزی نمایش نمیدهد


elevator.getElevationForLocations(positionalReques t, function (results, status, locations) {

باید بشه این شکلی


elevator.getElevationForLocations(positionalReques t, function (results, status, locations) {

Mohsen6558
دوشنبه 26 مهر 1389, 21:19 عصر
با تشکر از پاسخ شما
مشکل این هست که مقدار این رو من باید بدم به یه متغییری یعنی به این صورت که مثلا یه متغییر temp هست من می خوام که به اون متغییر عدد برگشتی رو اضافه کنم من الان با کد اولی و کد شما فقط می تونم یا alert کنم یا document.write و این پاسخگوی نیاز من نیست
چه پیشنهادی می کنین

در مورد عنوان هم واقعا کلافه شده بودم از این به بعد لحاظ می کنم

mehdi.mousavi
دوشنبه 26 مهر 1389, 21:52 عصر
مشکل این هست که مقدار این رو من باید بدم به یه متغییری یعنی به این صورت که مثلا یه متغییر temp هست من می خوام که به اون متغییر عدد برگشتی رو اضافه کنم


سلام.
خوب بدین شکل عمل کنید:

var temp = 100;
getElevation(new google.maps.LatLng(38.2567583333333, 48.3149633333333), function (elevation) {
temp += elevation;
});

حالا ممکنه temp از طریق یه function دیگه بدست بیاد و ... اگر بازهم پاسختون رو نگرفتید، لطفا کدتون رو قرار بدید و توضیح بدید دنبال چی هستید تا بهتون پاسخ بدم.

موفق باشید.

Mohsen6558
دوشنبه 26 مهر 1389, 21:56 عصر
نه درسته در جهت سوال پیش میریم مشکل اینجاست که این چیزی که بالا فرمودین جز 100 چیزی برنمی گردونه در واقع elevation صفر بر می گردونه که با صد جمع می شه می شه صد!


<html>
<head>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript">
var elevator = new google.maps.ElevationService();
function getElevation(event, onRequestCompleted) {

var locations = [];
var clickedLocation = event;
locations.push(clickedLocation);
var positionalRequest = {
'locations': locations
}

// Initiate the location request
elevator.getElevationForLocations(positionalReques t, function (results, status, locations) {
if (typeof onRequestCompleted == 'function') {
onRequestCompleted(results[0].elevation);
}
});
}
</script>
</head>
<body onload="initialize()">
<div id="map_canvas" style="width: 100%; height: 100%; float: left; border: 1px solid black;">
</div>
<script type="text/javascript">
var temp = 100;
getElevation(new google.maps.LatLng(38.2567583333333, 48.3149633333333), function (elevation) {
temp += elevation;
});
alert (temp);
</script>
</body>
</html>

mehdi.mousavi
دوشنبه 26 مهر 1389, 22:06 عصر
ببینید. هر کاری که مایلید انجام بدید باید در اون تابع انجام بدید. alert رو هم اگر به درون اون تابع بیارید مشکل رفع میشه:


var temp = 100;
getElevation(new google.maps.LatLng(38.2567583333333, 48.3149633333333), function (elevation) {
temp += elevation;
alert(temp);
});

در واقع ببینید چه اتفاقی میفته. شما به getElevationForLocations یه تابع معرفی میکنید که هر وقت کار گرفتن اطلاعات مورد نظر تموم شد، JavaScript Engine اون تابع رو فراخوانی کنه. این تابع بصورت Asynchronous اجرا میشه، یعنی صبر نمیکنه تا منتظر دریافت پاسخ بمونه (که این ایده آل هستش، چون اینطوری دیگه UI هم Freeze نمیشه). وقتی اجرای این تابع شروع شد، بلافاصله اجرا به خط بعدی getElevationForLocations میره، و هر وقت پاسخ دریافت شد، تابعی که بهش معرفی کرده اید فراخوانی میشه...

همه اینها رو گفتم که بگم تابع getElevation هم دقیقا اینطوری عمل میکنه. وقتی شما alert رو بیرون از تابعی که به getElevation داده ایم می نویسید، دیگه JS Engine منتظر نمیمونه تا پاسخ از سرور بیاد و اجرا به خط alert برسه. بلافاصله بعد از getElevation خطی که در اون alert رو نوشته بودید اجرا میشه و طبیعی هستش که عدد 100 رو ببینید. اما کدتون رو به کدی که نوشتم تغییر بدید. اینطوری دیگه هر وقت پاسخ از سرور دریافت بشه، مقدار temp با مقدار دریافت شده جمع میشه و alert هم مقدار جدید رو نشون میده.

موفق باشید.

Mohsen6558
دوشنبه 26 مهر 1389, 22:28 عصر
نمی شه از این حالت درش آورد؟
یعنی منتظر جواب باشه بعد بره خط بعد؟

mehdi.mousavi
دوشنبه 26 مهر 1389, 23:29 عصر
نمی شه از این حالت درش آورد؟ یعنی منتظر جواب باشه بعد بره خط بعد؟

من راستش با این API های گوگل کار نکرده ام، اما از نظر منطقی نباید چنین چیزی میسر باشه چون منجر به Block شدن Thread اصلی برنامه میشه. همونطوری که در پیام خصوصی هم خدمتتون عرض کردم، A در Ajax به معنای Asynchronous هستش، حالا شما میخواهید اینو به Synchronous تبدیل کنید و ... میدونم اولش قدری نامانوس بنظر میرسه، اما وقتی دارید با Ajax و اینطور API ها کار می کنید، این مساله اجتناب ناپذیره.

موفق باشید.