2011-08-25 69 views
14

Câu hỏi của tôi là về Javascript. Tôi có một chức năng gọi lại nhận một đối tượng Vị trí trên một cuộc gọi lại thành công.Javascript gán giá trị trả về của hàm Gọi lại cho biến toàn cục

Vấn đề là khi tôi cố gắng đặt thuộc tính của đối tượng Vị trí thành biến toàn cầu tại cuộc gọi lại thành công, nó không cho phép tôi làm điều đó và toàn cầu vẫn không được xác định.

Để giải quyết thay vì đặt trực tiếp thuộc tính đối tượng thành biến toàn cục, tôi đang cố trả về hàm gọi lại nhưng tôi không thể tìm cách đặt giá trị trả về của hàm gọi lại thành toàn cầu biến.

Đây là mã được đơn giản hóa.

var x; 

navigator.geolocation.getCurrentPosition(onSuccess, onError); 

//on Successful callback receives a Position Object 
function onSuccess(position) { 
    var coords = position.coords; 
    x=coords;  // Setting directly to an object does not work x still remains undefined after succesful callback    
return coord; // Trying to set this to a global object 

} 

// onError Callback receives a PositionError object 
// 
function onError(error) { 
    alert('code: ' + error.code + '\n' + 
      'message: ' + error.message + '\n'); 
} 

Trả lời

15

Bạn không thể trả lại giá trị từ cuộc gọi lại (trong trường hợp này). Điều đó có nghĩa là bên trong của getCurrentPosition, giá trị trả lại từ cuộc gọi lại phải được chỉ định ở đâu đó.

Gán nó cho biến toàn cầu hoạt động, nhưng tại thời điểm bạn truy cập biến đó, nó chưa được gán giá trị mới. Ví dụ.

// x is assigned in `onSuccess` 
var x; 
navigator.geolocation.getCurrentPosition(onSuccess, onError); 
alert(x); // will be undefined, the response is not processed yet 

Hãy nghĩ về điều đó: getCurrentPosition có thể đang thực hiện yêu cầu Ajax để nhận vị trí. Yêu cầu như vậy mất (a) thời gian (vài phần nghìn giây) và do đó (b) là không đồng bộ, có nghĩa là JavaScript không chờ cho đến khi nhận được phản hồi. Mã của bạn là cách nhanh hơn. onSuccess chưa được gọi khi bạn cảnh báo x.

giải pháp Chỉ:

Tất cả các mã có để truy cập vị trí như là trong hay còn gọi là từ gọi lại.

+0

điểm thực sự tốt, câu trả lời của tôi là một giám sát ngu ngốc trên một phần của tôi. mã không phải là tuyến tính vì vậy bạn sẽ cần phải làm bất cứ điều gì bạn muốn làm với các coords trong gọi lại, để đảm bảo giá trị đã được ràng buộc – WickyNilliams

+0

Bạn đang thực sự right.The chức năng getCurrentPosition đang cố gắng để có được vị trí địa lý đó là không đồng bộ đó là lý do tại sao khi tôi cố gắng truy cập nó từ biến toàn cục, có lẽ nó không được thiết lập và trả về undefined.Isnt có cách nào để gán biến trả về giá trị sau khi hàm async được thực hiện với công việc của nó không? –

+0

@Torukojin: Không, phải trả lại giá trị nào cho? Như đã nói, mã chạy không đồng bộ. Đó là lý do tại sao giá trị được chuyển như một tham số cho hàm gọi lại để bạn có thể sử dụng nó và làm bất cứ điều gì bạn muốn với nó. Nếu có thể 'trả về' giá trị, thì' getCurrentPosition' sẽ làm điều đó. Nhưng nó không phải là, do đó bạn đã cung cấp một cuộc gọi lại. Có thể bạn sẽ tìm thấy [bài viết này] (http://felix-kling.de/blog/2011/01/14/how-to-return-data-from-an-ajax-call/) hữu ích để hiểu vấn đề (nhưng tôi không phải là tốt bằng văn bản;)) –

0

bạn đã thử đặt nó qua đối tượng window toàn cầu chưa?

//on Successful callback receives a Position Object 
function onSuccess(position) { 
    var coords = position.coords; 
    window.x=coords;  // Setting directly to an object does not work x still remains undefined after succesful callback    
return coord; // Trying to set this to a global object 

} 

Ngoài ra, vì bạn trả lại tọa độ từ trình xử lý thành công, không còn cách nào khác để nhận giá trị này?

0

đặt một console.log(x); ngay sau x=cords để kiểm tra giá trị (chỉ hoạt động trên Chrome và FF với Firebug)

làm điều đó cũng chỉ sau khi cuộc gọi của onSuccess.

Cũng đừng quên rằng đó là mã không đồng bộ trong JS (nếu bạn sử dụng AJAX để có được vị trí), có thể bạn chỉ không nhận được câu trả lời khi bạn kiểm tra giá trị của x

+0

Thực ra tôi đã làm điều đó mặc dù tôi đã không đề cập đến :) –

1

Như mô tả của Felix King, bạn không thể trả về một giá trị từ một cuộc gọi lại và trong biến toàn cầu biến của bạn, biến sẽ không được đặt cho đến sau khi yêu cầu AJAX hoàn thành và gọi lại gọi lại (do đó tên của nó!).

Sử dụng biến toàn cục, bạn có thể giải quyết sự cố nếu bạn có một số loại vòng xử lý, bạn có thể thêm mã này vào vòng lặp đó để thực hiện những gì được yêu cầu bất cứ khi nào điều phối thay đổi.

if (coord) // global variable has a new value 
    // process it 
    alert('code: ' + error.code + '\n' + 
      'message: ' + error.message + '\n'); 
    // then clear it 
    coord = null; 
    } 
0

Bạn có thể thực hiện một phương pháp helper như chảy:

var LocationHelper = function() {}; 

LocationHelper.prototype.getLocation = function(callback) { 

    navigator.geolocation.getCurrentPosition(onSuccess, onError); 

    function onSuccess(pos) { 
     callback({ 
      pos: pos 
     }); 
    } 

    function onError(message) { 
     callback({ 
      message: message 
     }); 
    } 

    }; 
Các vấn đề liên quan