如何使用 Observable.bindCallback()?

8

我该如何使用Observable.bindCallback()来处理返回2个参数的回调函数callback(results, status)?下面是使用google.maps.places API的示例:

  const service = new google.maps.places.PlacesService(map);
  // service.nearbySearch(request, callback);


  function callback(results, status) {
    if (status === google.maps.places.PlacesServiceStatus.OK) {
      for (var i = 0; i < results.length; i++) {
        createMarker(results[i]);
      }
    }
  }

我想要做类似这样的事情:
const handleError = err=>console.error(error);

const nearbyAsObservable = Observable.bindCallback(service.nearbySearch)
nearbyAsObservable(request)
   .subscribe( 
     (results,status)=>{
       if (status!="OK") handleError(results);
       callback
     }
     , handleError
   )

但是我对以下内容不确定:

1)最佳实践是从next处理程序“抛出”错误并在error处理程序中捕获它,还是只调用方法handleError()

2)我收到Cannot read property 'nearbySearch' of undefined(…)错误。 但是当我调用const nearbyAsObservable = Observable.bindCallback( service.nearbySearch.bind(service) )时,我得到了一个TS错误:

// const nearbyAsObservable = Observable.bindCallback(service.nearbySearch.bind(service) )
// nearbyAsObservable(request)
[ts] Supplied parameters do not match any signature of call target.
const nearbyAsObservable: () => Observable<{}>

更新 看起来这个黑客攻击能够解决TS错误

const nearbyAsObservable : any = Observable.bindCallback(service.nearbySearch.bind(service) )
nearbyAsObservable(request)
   .subscribe( 
     (results,status)=>{
       if (status!="OK") handleError(results);
       callback
     }
     , handleError
   )

但是如果我给next处理程序传递(result, status)=>void,它会抱怨。

3)我如何将Observable<[result, status]>返回值转换为Observable<PlaceResult[]>


尝试使用 Observable.bindCallback(service.nearbySearch.bind(service)) - cartant
1
你如何知道你没有正确处理错误? - martin
我使用了与您相同的API来回答另一个问题,但是我无法再找到它了。 我只能假设该用户的帐户已被删除。需要一点时间才能记起详细信息。 - cartant
1
我想我找到了答案:在bindCallback()中使用选择器函数!我将在下面发布完整的答案。 - michael
没错,你需要使用选择器将回调函数中接收到的参数映射到一个数组或对象中,这就成为了绑定函数返回的可观察类型。 - cartant
1个回答

6
答案如下:
1)根据需要将范围绑定到您的回调函数(请参见注释)。
2)如果绑定了范围,则使用 let nearbyAsObservable : any; 修复 TS 错误我如何使用 `Observable.bindCallback()` with TypeScript 3)在 Observable.bindCallback() 中使用 selector 函数将多个返回参数映射到单个响应以进行 subscribe 函数,并抛出错误。我如何在 Observable.bindCallback 方法中使用 RXJS selector function?
let nearbyPlaces = function(position: google.maps.LatLng) : Observable<google.maps.places.PlaceResult[]> {  
  const service = new google.maps.places.PlacesService(map)
  // 1) bind scope
  const nearbySearchCallback = service.nearbySearch.bind(service)

  let nearbyAsObservable : any;
  // 2) type any fixes: 
  //    [ts] Supplied parameters do not match any signature of call target. 
  //    const nearbyAsObservable: () => Observable<{}>  

  nearbyAsObservable = Observable.bindCallback( 
    nearbySearchCallback        // with bound scope
    , (results, status) => {    // 3) selector function
        if (status != google.maps.places.PlacesServiceStatus.OK) throw {status, results};
        return results  
      }
  );
  const placeRequest = {
    location: position,
    radius: 25,
    rankBy: google.maps.places.RankBy.PROMINENCE,
  }
  return nearbyAsObservable(placeRequest) as Observable<google.maps.places.PlaceResult[]>
}


// usage example:
nearbyPlaces(position).subscribe(
  (results:google.maps.places.PlaceResult[])=>console.log(results)
  , err=>console.error(err)
)

如果你将 bind 的结果转换为 (request: PlaceSearchRequest, callback: (results: PlaceResult[], status: PlacesServiceStatus) => void) => void,它应该可以很好地与 TypeScript 协作,并且参数类型应该可以被推断出来,但这是一个又长又丑的转换。 - cartant

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接