首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JS promise inside promise

JS promise inside promise
EN

Stack Overflow用户
提问于 2017-01-04 17:14:56
回答 2查看 3.2K关注 0票数 0

应该在3次尝试中检索位置的getLocation()函数返回undefinednavigator.geolocation.getCurrentPosition()返回正确的位置,但问题出在promise处理上。

显然,问题是我把promise称为inside promise。不允许在已声明为asyncgeolocate()中使用await关键字。

原始呼叫:

代码语言:javascript
复制
var getLocationPromise = this.getLocation();
// Do something...
location = await getLocationPromise;

getLocation()

代码语言:javascript
复制
  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()

代码语言:javascript
复制
  async geolocate() {
    return new Promise((resolve, reject) => {

      navigator.geolocation.getCurrentPosition(
        (position) => {
          resolve(position);
        },
        (err) => {
          reject(err);
        },
        {enableHighAccuracy: true, timeout: 20000, maximumAge: 1000}
      );
    });
  }
EN

回答 2

Stack Overflow用户

发布于 2017-01-04 20:24:29

只要在声明为async的函数中包含以下内容

代码语言:javascript
复制
var getLocationPromise = this.getLocation();
// Do something...
location = await getLocationPromise;

按原样应该没问题

查看getLocation/ geolocate,除非您需要单独的geolocate方法,否则它们应该能够组合并简化为

代码语言:javascript
复制
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);
}
票数 2
EN

Stack Overflow用户

发布于 2020-08-28 18:53:49

异步和等待

不能在没有async关键字的函数中使用await。因此,出现该错误是因为执行器函数不是async

代码语言:javascript
复制
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

代码语言:javascript
复制
new Promise( async function( resolve, reject ){ // <-- BAD ! Don't do it !
   ...
})

没有嵌套的promise

但是由于getLocation已经是一个承诺,您根本不需要嵌套的new Promise( ... )

代码语言:javascript
复制
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?)。

代码语言:javascript
复制
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()函数中的任何差异。诸若此类。

代码语言:javascript
复制
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"
})
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41460058

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档