等到条件成立?

Ric*_*ard 21 javascript geolocation

navigator.geolocation.watchPosition在JavaScript中使用,我想要一种方法来处理用户在watchPosition找到位置之前提交依赖于位置的表单的可能性.

理想情况下,用户会定期看到"等待位置"消息,直到获得该位置,然后表单将提交.

但是,由于缺少wait函数,我不确定如何在JavaScript中实现它.

当前代码:

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...
});
Run Code Online (Sandbox Code Playgroud)

小智 26

就个人而言,我使用的waitfor()函数封装了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();
}
Run Code Online (Sandbox Code Playgroud)

waitfor()以下列方式使用我的函数:

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 !');
});
Run Code Online (Sandbox Code Playgroud)

  • 但是如果在最终(也就是初始)waitfor调用之下有更多代码,那么代码是否会继续执行,直到它暂停,因为它是时候运行第一个调度的setTimeout调用?最初waitfor只是一个设置setTimeout调用然后返回的函数.您的代码将*监视*直到值更改,但它不会*阻止*直到值更改. (2认同)

Ben*_*ler 13

这正是承诺的发明和实施(因为OP问他的问题).

查看所有各种实现,例如promisejs.org

  • @HansWesterbeek可能是因为承诺的概念是一个广泛的主题.我已经有一种感觉,我应该使用一个承诺,但这个答案太模糊,无法帮助我. (15认同)
  • 这是这个问题的唯一正确答案,到目前为止它有0票真的很令人担忧 (3认同)

Nic*_*ole 12

你会想要使用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();
    }
}
Run Code Online (Sandbox Code Playgroud)

... getLocation查找您的位置.


Chr*_*ett 7

您可以使用超时尝试重新提交表单:

$('#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...
    }
});
Run Code Online (Sandbox Code Playgroud)


Lig*_*ard 7

使用Promise的现代解决方案

function waitFor(conditionFunction) {

  const poll = resolve => {
    if(conditionFunction()) resolve();
    else setTimeout(_ => poll(resolve), 400);
  }

  return new Promise(poll);
}
Run Code Online (Sandbox Code Playgroud)

用法

waitFor(_ => flag === true)
  .then(_ => console.log('the wait is over!'));
Run Code Online (Sandbox Code Playgroud)

要么

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

参考
承诺
箭头功能
异步/等待