如何在线性流之后链接承诺?

Posted

技术标签:

【中文标题】如何在线性流之后链接承诺?【英文标题】:How to chain promises following linear flow? 【发布时间】:2019-02-12 13:02:30 【问题描述】:

我的流程有问题,我正在使用承诺来做到这一点

上下文是:用户单击按钮以使用离子地理定位获取您的位置,ir 返回 lat 和 log ,然后我想解码坐标以获取 City,最后一步设置 lat、long 和 city用户。

tryGeolocation()        
    this.geolocation.getCurrentPosition().then((resp) => 
      let pos = 
        lat: resp.coords.latitude,
        lng: resp.coords.longitude
      ;
      this.lat = resp.coords.latitude;
      this.long = resp.coords.longitude;          
      console.log(this.lat+"--"+this.long);
      this.decodeCoord(this.lat, this.long);
      alert(this.city);
      this.uploadLocation();    
    ).catch((error) => 
      console.log('Error getting location', error);
      this.loading.dismiss();
    );
  



 decodeCoord(lat, long)     
    console.log("decodeCoord");
    var latlng = new google.maps.LatLng(lat, long);
    this.geocoder.geocode('latLng': latlng, function (results, status) 
      if (status == google.maps.GeocoderStatus.OK)        
        if (results[1]) 
          var indice = 0;
          for (var j = 0; j < results.length; j++) 
            if (results[j].types[0] == 'locality') 
              indice = j;
              break;
            
             

          let city, region, country;
          for (var i = 0; i < results[j].address_components.length; i++) 
            if (results[j].address_components[i].types[0] == "locality") 
              //this is the object you are looking for City
              city = results[j].address_components[i];
            
            if (results[j].address_components[i].types[0] == "administrative_area_level_1") 
              //this is the object you are looking for State
              region = results[j].address_components[i];
            
            if (results[j].address_components[i].types[0] == "country") 
              //this is the object you are looking for
              country = results[j].address_components[i];
            
          
          //city data        
          this.city=city;
         else 
          console.log("No results found");
                   
       else 
        console.log("Geocoder failed due to: " + status);
      
    );      
  



uploadLocation()    
    let position = 
      latitude: this.lat,
      longitude: this.long,
      city: this.city
      
    this._us.updateUserIndividual(position).then(data =>       
      console.log("USER UPDATED");
    ).catch((err) => 
      this.presentToast("Ups! Ha ocurrido un Error, intentalo otra vez");
    )
  

我试过添加 this.decodeCoord(this.lat, this.long);在 uploadLocation 上,但它也不起作用。

这座城市总是空荡荡的。

【问题讨论】:

我已经更新了我的答案。第一次读你的问题有点错误,如果有帮助请告诉我 是的@PierreDuc,谢谢 也许问题名称不正确@PierreDuc,你能建议我写什么名字来帮助其他人吗? 没关系,你的代码中有多个问题 :) 我首先只关注一个 【参考方案1】:

this.city 是空的,因为您在单独的 this 上下文中分配它。您在定义this.geocoder.geocode() 时创建了这个新上下文,并使用function 关键字创建回调函数。用箭头函数替换它,我想你又好了:

this.geocoder.geocode('latLng': latlng, (results, status) => 
  // ...
);

但我大错特错了。

this.decodeCoord(this.lat, this.long);
alert(this.city);

那是行不通的。因为我让你改变的回调函数,顾名思义,是一个异步函数。所以最好的办法是从decodeCoord 方法返回一个Promise

decodeCoord(lat, long)     
  return new Promise((resolve, reject) => 
    // ...
    this.geocoder.geocode('latLng': latlng, (results, status) => 
      if (status == google.maps.GeocoderStatus.OK)  
        // ...
        resolve();
       else 
        reject();
      
    );
  );

然后你甚至还没有到那里,你还需要从你的updateLocation 方法返回承诺:

return this._us.updateUserIndividual(position).

然后你可以改变你的tryGeolocation方法:

async tryGeolocation()    
  try 
    const  coords  = await this.geolocation.getCurrentPosition();
    this.lat = coords.latitude;
    this.long = coords.longitude;          

    await this.decodeCoord(coords.latitude, coords.longitude);
    alert(this.city);
    await this.uploadLocation(); 
   catch (e) 
    console.log('Error getting location', e);
    finally 
    this.loading.dismiss();  
  

你已经完成了,一个很好的顺序异步等待结果

【讨论】:

非常感谢@pierreDuc 我已经实现了它,它运行得很好 我怎样才能知道代码在哪里中断?在这种情况下,我想知道等待失败的那一行,有什么解决方案可以知道吗? 堆栈跟踪会告诉你。只需将console.log 更改为console.error。并且控制台中会有一个stacktrace

以上是关于如何在线性流之后链接承诺?的主要内容,如果未能解决你的问题,请参考以下文章

如何让 React Redux 异步操作返回一个承诺?

如何在Angular 6的循环中链接承诺

如何在 knex.js 迁移中链接承诺

我如何链接多个承诺?

如何在 JS 中使用 try、catch、.then 链接和异步等待来解决承诺?

jQuery承诺,如何检查then()是否真的在when()之后?