等待函数结束,使用React Native下的UnderscoreJS设置状态

时间:2016-06-06 17:18:55

标签: javascript react-native underscore.js

我想进行提取,然后更新标记状态。问题是在我的提取结束之前状态正在更新(由于异步,我认为)。我认为UnderscoreJS会使用_.after函数在我的fetch结束后设置状态。我不知道该怎么做。有什么想法吗?

这是我的代码:

onRegionChange(region) {

  let latitude = region.latitude;
  let longitude = region.longitude;

  let markers = [];

  _.filter(this.props.stations, (v) => 
    {
      if (this.getDistanceFromLatLonInKm(latitude,longitude,v.position.lat,v.position.lng) < 1) {

        fetch('https://api.jcdecaux.com/vls/v1/stations/' + v.number + '?contract=Paris&apiKey=3a9169028401f05f02bcffd87f4a3963dcd52f63')
          .then((response) => response.json())
          .then((station) => {
            console.log("station", station);
            markers.push({
              number: station.number,
              coordinate: {
                latitude: station.position.lat,
                longitude: station.position.lng
              },
              title: station.name,
              description: station.address,
              banking: station.banking,
              bonus: station.bonus,
              status: station.status,
              bike_stands: station.bike_stands,
              available_bike_stands: station.available_bike_stands,
              available_bikes: station.available_bikes,
              last_update: station.last_update
            });
          })
          .catch((error) => {
            console.warn(error);
          });

      }

    }

  )

  this.setState({
    markers: markers
  })

  console.log("markers", this.state.markers);

}

1 个答案:

答案 0 :(得分:0)

混合同步和异步的想法,它们混合不好。

最好将同步值转换为promises(fetch正在做的事情)。

首先,我将传动部件分解为功能。这样可以清理实际代码并降低复杂性。

function stationFetchUrl(station) {
  return `https://api.jcdecaux.com/vls/v1/stations/${station.number}?contract=Paris&apiKey=3a9169028401f05f02bcffd87f4a3963dcd52f63`;
}

function convertStationData(station) {
  return {
    number: station.number,
    coordinate: {
      latitude: station.position.lat,
      longitude: station.position.lng
    },
    title: station.name,
    description: station.address,
    banking: station.banking,
    bonus: station.bonus,
    status: station.status,
    bike_stands: station.bike_stands,
    available_bike_stands: station.available_bike_stands,
    available_bikes: station.available_bikes,
    last_update: station.last_update
  };
}

function stationNearRegion(region, station) {
  const distance = this.getDistanceFromLatLonInKm(
    region.latitude,
    region.longitude,
    stationStub.position.lat,
    stationStub.position.lng
  );
  return (distance < 1);
}

接下来在事件处理程序中我映射在工作站上并将它们转换为null(在距离为>= 1的情况下)或获取新工作站数据来自服务器(fetch())。

这会产生一个promises或null数组。我使用Underscore的.compact()来删除null(与过滤器相同)。然后我有一个承诺数组,我传递给Promise.all,等待数组中的所有承诺解析。当他们这样做时,它将这些承诺的结果(作为数组)传递给.then()函数,我尽职尽责地使用this.setState()

onRegionChange(region) {
  const markerPromises = _.chain(this.props.stations)
    .map(stationStub => {
      if (stationNearRegion.call(this, region, stationStub) {
        return fetch(stationFetchUrl(station))
          .then(response => response.json())
          .then(convertStationData);
      }
    })
    .compact()
    .value();

  Promise.all(markerPromises)
    .then(markers => this.setState({markers}))
    .catch(error => console.log(error.toString()));
});

由于onRegionChange是一个事件处理程序,因此它不会返回一个promise。相反,我们通过在.catch()块中记录它们来处理可能的错误。

参考