2011-08-25 30 views
18

Tôi đang sử dụng navigator.geolocation.watchPosition bằng JavaScript và tôi muốn có cách để giải quyết khả năng người dùng có thể gửi biểu mẫu dựa vào vị trí trước khi watchPosition tìm thấy vị trí của nó.Đợi cho đến khi điều kiện là đúng?

Lý tưởng nhất là người dùng sẽ thấy thông báo 'Đang chờ vị trí' định kỳ cho đến khi có được vị trí, sau đó biểu mẫu sẽ gửi.

Tuy nhiên, tôi không chắc chắn cách triển khai điều này trong JavaScript do thiếu chức năng wait.

đang hiện tại:

var current_latlng = null; 
function gpsSuccess(pos){ 
    //console.log('gpsSuccess'); 
    if (pos.coords) { 
     lat = pos.coords.latitude; 
     lng = pos.coords.longitude; 
    } 
    else { 
     lat = pos.latitude; 
     lng = pos.longitude; 
    } 
    current_latlng = new google.maps.LatLng(lat, lng); 
} 
watchId = navigator.geolocation.watchPosition(gpsSuccess, 
        gpsFail, {timeout:5000, maximumAge: 300000}); 
$('#route-form').submit(function(event) { 
    // User submits form, we need their location... 
    while(current_location==null) { 
     toastMessage('Waiting for your location...'); 
     wait(500); // What should I use instead? 
    } 
    // Continue with location found... 
}); 
+0

Suy nghĩ không đồng bộ. Tra cứu 'setTimeout'. –

+0

Không đồng bộ và đệ quy có thể - đệ quy gọi setTimeout cho đến khi current_latlng có một số giá trị? – Richard

+0

hiểu ngôn ngữ đầu tiên trước khi đổ lỗi cho ngôn ngữ đó. Không có "thiếu" của một chức năng 'chờ đợi 'cho chắc chắn. – jAndy

Trả lời

7

Bạn có thể sử dụng một thời gian chờ để cố gắng tái gửi biểu mẫu:

$('#route-form').submit(function(event) { 
    // User submits form, we need their location... 
    if(current_location==null) { 
     toastMessage('Waiting for your location...'); 
     setTimeout(function(){ $('#route-form').submit(); }, 500); // Try to submit form after timeout 
     return false; 
    } else { 
     // Continue with location found... 
    } 
}); 
+0

Ew. Không chuyển biểu thức trong chuỗi. –

+0

Nó cần phải là một chuỗi, nếu không thì thời gian chờ sẽ nhận được giá trị của .submit. Tôi cho rằng bạn có thể làm hàm() {return $ ('# route-form'). Submit(); }. Tôi nghĩ rằng sẽ làm việc. –

+0

Tôi không hiểu câu đầu tiên của bạn cả. Và, vâng, một biểu hiện hàm là cách thích hợp để đi. :) –

12

Bạn sẽ muốn sử dụng setTimeout:

function checkAndSubmit(form) { 
    var location = getLocation(); 
    if (!location) { 
     setTimeout(checkAndSubmit, 500, form); // setTimeout(func, timeMS, params...) 
    } else { 
     // Set location on form here if it isn't in getLocation() 
     form.submit(); 
    } 
} 

... nơi getLocation nhìn lên vị trí của bạn.

+0

Bạn cũng có thể đặt cờ trong 'gpsFail', sau đó kiểm tra điều này trong' checkAndSubmit' và hiển thị thông báo thích hợp. –

23

Cá nhân, tôi sử dụng một hàm waitfor() mà gói gọn một setTimeout():

//********************************************************************** 
// function waitfor - Wait until a condition is met 
//   
// Needed parameters: 
// test: function that returns a value 
// expectedValue: the value of the test function we are waiting for 
// msec: delay between the calls to test 
// callback: function to execute when the condition is met 
// Parameters for debugging: 
// count: used to count the loops 
// source: a string to specify an ID, a message, etc 
//********************************************************************** 
function waitfor(test, expectedValue, msec, count, source, callback) { 
    // Check if condition met. If not, re-check later (msec). 
    while (test() !== expectedValue) { 
     count++; 
     setTimeout(function() { 
      waitfor(test, expectedValue, msec, count, source, callback); 
     }, msec); 
     return; 
    } 
    // Condition finally met. callback() can be executed. 
    console.log(source + ': ' + test() + ', expected: ' + expectedValue + ', ' + count + ' loops.'); 
    callback(); 
} 

tôi sử dụng chức năng waitfor() của tôi trong theo cách sau:

var _TIMEOUT = 50; // waitfor test rate [msec] 
var bBusy = true; // Busy flag (will be changed somewhere else in the code) 
... 
// Test a flag 
function _isBusy() { 
    return bBusy; 
} 
... 

// Wait until idle (busy must be false) 
waitfor(_isBusy, false, _TIMEOUT, 0, 'play->busy false', function() { 
    alert('The show can resume !'); 
}); 
+0

đừng quên ');' ở cuối hàm 'waitfor()' –

+0

thx, chính xác những gì tôi cần –

+2

Nhưng nếu có nhiều mã bên dưới cuộc gọi waitfor cuối cùng (còn gọi là ban đầu), sẽ không phải mã đó tiếp tục thực thi, cho đến khi nó tạm dừng vì đã đến lúc chạy lệnh setTimeout được lên lịch đầu tiên? ban đầu waitfor chỉ là một hàm thiết lập một cuộc gọi setTimeout và sau đó trả về. mã của bạn sẽ * xem * cho đến khi giá trị thay đổi, nhưng nó sẽ không * chặn * cho đến khi giá trị thay đổi. –

14

Đây chính xác những gì hứa hẹn đã được phát minh và thực hiện (kể từ khi OP hỏi câu hỏi của mình) cho.

Xem tất cả các triển khai khác nhau, ví dụ: promisejs.org

+3

đây là câu trả lời đúng duy nhất cho câu hỏi và nó thực sự lo lắng rằng nó đã có 0 phiếu cho đến bây giờ –

+11

@ HansWesterbeek có lẽ vì khái niệm về lời hứa là một chủ đề rộng. Tôi đã có một cảm giác rằng tôi nên sử dụng một lời hứa, nhưng câu trả lời này là quá mơ hồ để giúp tôi. – Stijn

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