可观察返回单个数组

时间:2017-12-13 22:20:41

标签: javascript angular rxjs

问题:

我想一次返回一个数组,而不是一个一个地返回多个数组。

代码:

fetchAllRiders() {
  var distanceObs = Observable.create(observer => {
    this.http.get(this.API + '/driver/all').map(res => res.json())
      .subscribe(data => data.map(rider => {
          this.geocoder.geocode({
            location: {
              lat: rider.driver_lat,
              lng: rider.driver_lng
            }
          }, (results, status) => {
            if (status == google.maps.GeocoderStatus.OK) {
              this.distanceMatrixService.getDistanceMatrix({
                  origins: [this.from],
                  destinations: [results[0].formatted_address],
                  travelMode: google.maps.TravelMode.DRIVING
                },
                (response, status) => {
                  if (status == google.maps.DistanceMatrixStatus.OK) {
                    this.distances.push({
                      distance: response.rows[0].elements[0].distance.value,
                      rider_id: rider._id
                    })
                  }
                })
              observer.next(this.distances);
            }
          })
        })
        //looping ends 
      )
  })
  return distanceObs
}

在完成所有推送后,如何获取阵列?

3 个答案:

答案 0 :(得分:1)

此代码中存在以下几个问题:

如果正确重写,它可能如下所示:

function fetchAllRiders() {
  // it's better to rewrite this services so they will return Observable insated of using callback
  const geocode = Observable.bindCallback(this.geocoder.geocode);
  const getDistanceMatrix = Observable.bindCallback(this.distanceMatrixService.getDistanceMatrix);

  return this.http
    .get(this.API + '/driver/all')
    .switchMap(res => res.json())
    .mergeMap(rider =>
      geocode({
        location: {
          lat: rider.driver_lat,
          lng: rider.driver_lng,
        },
      })
        .filter(([results, status]) => status === google.maps.GeocoderStatus.OK)
        .switchMap(([results]) =>
          getDistanceMatrix({
            origins: [this.from],
            destinations: [results[0].formatted_address],
            travelMode: google.maps.TravelMode.DRIVING,
          }),
        )
        .filter(([results, status]) => status === google.maps.DistanceMatrixStatus.OK)
        .map(([response]) => ({
          distance: response.rows[0].elements[0].distance.value,
          rider_id: rider._id,
        })),
    )
    .toArray();
}

答案 1 :(得分:0)

Observable subscribe实现了3种方法:onNextonErroronCompleted

.subscribe( 
data=>{ onNext},
err=>{ onError},
()=>{ onCompleted}
)

onCompleted将触发onNext的上一次迭代。您可以在onCompleted中定义下一个。

有关详细信息,请参阅http://reactivex.io/documentation/operators/subscribe.html

答案 2 :(得分:0)

我的观点是首先从'Api / driver / all'中获取数据。在subscribe方法中,您有3种方法可以实现。 'OnNext', 'OnError'and'OnCompleted'。您可以错误地返回observable并完成。

请检查以下代码

 this.http.get(this.API + '/driver/all').map(res => res.json())
        .subscribe(
            data => {data.map(
                rider => {
            this.geocoder.geocode({
              location: {
                lat: rider.driver_lat,
                lng: rider.driver_lng
              }
            }, (results, status) => {
              if (status == google.maps.GeocoderStatus.OK) {
                this.distanceMatrixService.getDistanceMatrix({
                    origins: [this.from],
                    destinations: [results[0].formatted_address],
                    travelMode: google.maps.TravelMode.DRIVING
                  },
                  (response, status) => {
                    if (status == google.maps.DistanceMatrixStatus.OK) {
                      this.distances.push({
                        distance: response.rows[0].elements[0].distance.value,
                        rider_id: rider._id
                      })
                    }
                  })

              }
            });
          })
          //looping ends 
        },
        err=>{
            return Observable.create(observer=>{
                observer.next(this.distances);
            })
        },
        ()=>{
            return Observable.create(observer=>{
                observer.next(this.distances);
            })
        })