Javascript 等到条件为真?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7193238/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Wait until a condition is true?
提问by Richard
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 location before watchPosition
has found its location.
我navigator.geolocation.watchPosition
在 JavaScript 中使用,我想要一种方法来处理用户可能在watchPosition
找到其位置之前提交依赖于位置的表单的可能性。
Ideally the user would see a 'Waiting for location' message periodically until the location was obtained, then the form would submit.
理想情况下,用户会定期看到“等待位置”消息,直到获得位置,然后提交表单。
However, I'm not sure how to implement this in JavaScript given its lack of a wait
function.
但是,由于缺少wait
函数,我不确定如何在 JavaScript 中实现它。
Current code:
当前代码:
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...
});
采纳答案by Chris Pickett
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...
}
});
回答by Martin Mohnhaupt
Personally, I use a waitfor()
function which encapsulates a setTimeout()
:
就个人而言,我使用一个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();
}
I use my waitfor()
function in the following way:
我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 !');
});
回答by Lightbeard
Modern solution using Promise
使用 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
回答by Nicole
You'll want to use setTimeout
:
你会想要使用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.
...在哪里getLocation
查找您的位置。
回答by Ben Wheeler
This is precisely what promises were invented and implemented (since OP asked his question) for.
这正是 Promise 的发明和实现(因为 OP 提出了他的问题)。
See all of the various implementations, eg promisejs.org
查看所有各种实现,例如 promisejs.org
回答by Sajjad
class App extends React.Component {
componentDidMount() {
this.processToken();
}
processToken = () => {
try {
const params = querySearch(this.props.location.search);
if('accessToken' in params){
this.setOrderContext(params);
this.props.history.push(`/myinfo`);
}
} catch(ex) {
console.log(ex);
}
}
setOrderContext (params){
//this action calls a reducer and put the token in session storage
this.props.userActions.processUserToken({data: {accessToken:params.accessToken}});
}
render() {
return (
<Switch>
//myinfo component needs accessToken to retrieve my info
<Route path="/myInfo" component={InofUI.App} />
</Switch>
);
}
And then inside InofUI.App
然后在 InofUI.App 里面
componentDidMount() {
this.retrieveMyInfo();
}
retrieveMyInfo = async () => {
await this.untilTokenIsSet();
const { location, history } = this.props;
this.props.processUser(location, history);
}
untilTokenIsSet= () => {
const poll = (resolve) => {
const { user } = this.props;
const { accessToken } = user;
console.log('getting accessToken', accessToken);
if (accessToken) {
resolve();
} else {
console.log('wating for token .. ');
setTimeout(() => poll(resolve), 100);
}
};
return new Promise(poll);
}
回答by openwonk
Try using setInterval
and clearInterval
like this...
尝试使用setInterval
并clearInterval
喜欢这个......
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...
}
});