Wait until a condition is true?

前端 未结 7 1917
日久生厌
日久生厌 2020-12-09 08:32

I\'m using navigator.geolocation.watchPosition in JavaScript, and I want a way to deal with the possibility that the user might submit a form relying on locatio

相关标签:
7条回答
  • 2020-12-09 09:11

    Personally, I use a waitfor() function which encapsulates a 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();
    }
    

    I use my waitfor() function in the following way:

    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 讨论(0)
  • 2020-12-09 09:11

    Try using setInterval and clearInterval like this...

    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...
        // Checks status every half-second
        var watch = setInterval(task, 500)
    
        function task() {
            if (current_latlng != null) {
                clearInterval(watch)
                watch = false
                return callback()
            } else {
                toastMessage('Waiting for your location...');
    
            }
        }
    
        function callback() {
            // Continue on with location found...
        }
    });
    
    0 讨论(0)
  • 2020-12-09 09:15

    This is precisely what promises were invented and implemented (since OP asked his question) for.

    See all of the various implementations, eg promisejs.org

    0 讨论(0)
  • 2020-12-09 09:20

    Modern solution using Promise

    function waitFor(conditionFunction) {
    
      const poll = resolve => {
        if(conditionFunction()) resolve();
        else setTimeout(_ => poll(resolve), 400);
      }
    
      return new Promise(poll);
    }
    

    Usage

    waitFor(_ => flag === true)
      .then(_ => console.log('the wait is over!'));
    

    or

    async function demo() {
      await waitFor(_ => flag === true);
      console.log('the wait is over!');
    }
    

    References
    Promises
    Arrow Functions
    Async/Await

    0 讨论(0)
  • 2020-12-09 09:20

    You'll want to use 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();
        }
    }
    

    ... where getLocation looks up your location.

    0 讨论(0)
  • 2020-12-09 09:28

    You could use a timeout to try to re-submit the form:

    $('#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 讨论(0)
提交回复
热议问题