2011-08-25 25 views
18

Estoy usando navigator.geolocation.watchPosition en JavaScript, y quiero una forma de tratar con la posibilidad de que el usuario pueda enviar un formulario confiando en la ubicación antes de que watchPosition haya encontrado su ubicación.¿Esperar hasta que una condición sea verdadera?

Idealmente, el usuario vería periódicamente el mensaje "Esperando ubicación" hasta que se obtuviera la ubicación, luego se enviaría el formulario.

Sin embargo, no estoy seguro de cómo implementar esto en JavaScript dada su falta de una función wait.

código actual:

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

Piense asincrónicamente. Busque 'setTimeout'. –

+0

¿Quizás de manera asíncrona y recursiva, recursivamente llame a setTimeout hasta que current_latlng tenga algún valor? – Richard

+0

entiende el idioma primero antes de culparlo. No hay ninguna "falta" de una función de 'espera' de seguro. – jAndy

Respuesta

7

Se puede usar un tiempo de espera para tratar de volver a enviar el formulario:

$('#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. No pase expresiones en cadenas. –

+0

Tiene que ser una cadena, de lo contrario, el tiempo de espera obtendrá el valor de .submit. Supongo que podría hacer funcionar() {return $ ('# route-form'). Submit(); }. Creo que eso funcionaría –

+0

No entiendo tu primera oración en absoluto. Y, sí, una expresión de función es la forma correcta de hacerlo. :) –

12

usted querrá utilizar 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(); 
    } 
} 

... donde getLocation alza la vista de su ubicación.

+0

También puede colocar la bandera en 'gpsFail' y luego verificar esto en' checkAndSubmit' y mostrar el mensaje apropiado. –

23

Personalmente, yo uso una función waitfor() que encapsula un 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(); 
} 

uso mi función waitfor() en De la siguiente manera:

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

no olvide el ');' al final de la función 'waitfor()' –

+0

thx, exactamente lo que necesitaba –

+2

Pero si hay más código debajo de la llamada de espera final (alias la inicial), ¿no será ese el código? continuar ejecutando, hasta que haga una pausa porque es hora de ejecutar la primera llamada setTimeout programada? inicialmente waitfor es solo una función que configura una llamada a setTimeout y luego regresa. su código * mirará * hasta que el valor cambie, pero no * bloqueará * hasta que el valor cambie. –

14

Esto es precisamente qué promesas se inventaron e implementaron (desde que OP hizo su pregunta) para.

Vea todas las diversas implementaciones, por ejemplo, promisejs.org

+3

esta es la única respuesta correcta a la pregunta y es realmente preocupante que haya tenido 0 votos hasta ahora –

+11

@HansWesterbeek probablemente porque el concepto de promesas es un tema amplio. Ya tenía la sensación de que debería usar una promesa, pero esta respuesta es demasiado vaga para ayudarme. – Stijn

Cuestiones relacionadas