应该在3次尝试中检索位置的getLocation()函数返回undefined。navigator.geolocation.getCurrentPosition()返回正确的位置,但问题出在promise处理上。
显然,问题是我把promise称为inside promise。不允许在已声明为async的geolocate()中使用await关键字。
原始呼叫:
var getLocationPromise = this.getLocation();
// Do something...
location = await getLocationPromise;getLocation()
async getLocation() {
return new Promise((resolve, reject) => {
var geolocate;
for (let i=0; i<3; i++) {
geolocate = this.geolocate();
try {
var location = geolocate;//CAN'T USE AWAIT INSIDE ASYNC...
resolve(location);
} catch(err) {
continue;
}
}
reject("Max geolocation attempts");
});
}geolocate()
async geolocate() {
return new Promise((resolve, reject) => {
navigator.geolocation.getCurrentPosition(
(position) => {
resolve(position);
},
(err) => {
reject(err);
},
{enableHighAccuracy: true, timeout: 20000, maximumAge: 1000}
);
});
}发布于 2017-01-04 20:24:29
只要在声明为async的函数中包含以下内容
var getLocationPromise = this.getLocation();
// Do something...
location = await getLocationPromise;按原样应该没问题
查看getLocation/ geolocate,除非您需要单独的geolocate方法,否则它们应该能够组合并简化为
getLocation() {
var geolocate = () =>
new Promise((resolve, reject) =>
navigator.geolocation.getCurrentPosition(resolve, reject, {
enableHighAccuracy: true,
timeout: 20000,
maximumAge: 1000
});
);
// this function will "retry" the supplied function (fn) cont times
var limitedPromiseRetry = (fn, cont) => fn().catch(err => cont > 0 ? limitedPromiseRetry(fn, cont-1) : Promise.reject('Max number of geolocation attempts'));
return limitedPromiseRetry(geolocate, 3);
}发布于 2020-08-28 18:53:49
异步和等待
不能在没有async关键字的函数中使用await。因此,出现该错误是因为执行器函数不是async
var getLocation = async function(){ // <-- this function has "async" keyword, but ...
return new Promise( function( resolve, reject ){ // <-- ... this "executor" function has no "async" keyword.
var value = await geolocate(); // <-- ERROR: await is only valid in async function.
resolve( value );
})
};但是不应该让promise executor成为一个async函数。
有关详细信息,请参阅https://eslint.org/docs/rules/no-async-promise-executor。
new Promise( async function( resolve, reject ){ // <-- BAD ! Don't do it !
...
})没有嵌套的promise
但是由于getLocation已经是一个承诺,您根本不需要嵌套的new Promise( ... ):
var getLocation = async function(){ // <-- "async" makes a function to be a promise
var value = await geolocate();
// "return value" inside async function is "the same" as
// "resolve( value )" in a promise
return value;
};所以,从理论上讲,你可以用下面的方法来解决你的问题(尽管可能有更好的方法。有关异步函数内部的“拒绝”,请参见(另请参阅How to reject in async/await syntax?)。
var getLocation = async function(){
for( let i = 0; i < 3; i++ ){
try {
console.log('try ...', i);
var location = await geolocate(i);
console.log('... success');
return location;
} catch(err) {
console.log('... next try');
continue;
}
}
return Promise.reject('no success');
};
getLocation().then(function(result){
console.log('then:', result);
}).catch(function(reason){
console.log('error:', reason);
})嵌套承诺
承诺里面的承诺是可以的。
请注意,使用已解决的承诺解决承诺的行为与只解决一个承诺的行为“相同”。无论是解析一个值,还是解析promise内部的promise,您都不会注意到.then()函数中的任何差异。诸若此类。
var nestedPromises = new Promise( function( resolve1, reject1 ){
resolve1( new Promise( function( resolve2, reject2 ){
resolve2( new Promise( function( resolve3, reject3 ){
resolve3('resolved value');
}));
}));
});
nestedPromises.then( function( value ){
console.log('value:', value); // <-- "value: resolved value"
})https://stackoverflow.com/questions/41460058
复制相似问题