当我的程序获取天气数据时,我正在尝试制作一个简单的进度计数器,从0%到100%. API请求由index.ios.js中的getLocation()生成,该函数调用weatherApi.js中的fetchWeather().有没有办法衡量fetch函数对我的API请求的进度?如果没有,实施加载栏的好方法是什么?
weatherAPI.js
const rootUrl ='http://api.openweathermap.org/data/2.5/weather?appid=fcea54d0ceade8f08ab838e55bc3f3c0' export const fetchWeather = (lat,lon) => { const url = rootUrl+'&lat='+lat+'&lon='+lon+"&units=metric" console.log(url) return fetch(url) .then(res => res.json()) .then(json => ({ temp: json.main.temp,weather: json.weather[0].main })) }
index.ios.js
import React,{Component} from 'react'; import { AppRegistry,StyleSheet,Text,View,StatusBar } from 'react-native' import Icon from 'react-native-vector-icons/Ionicons' import {fetchWeather} from './weatherAPI' import Highlight from 'react-native-highlight-words' const iconNames = { Default: 'md-time',Clear: 'md-sunny',Rain: 'md-rainy',Thunderstorm: 'md-thunderstorm',Clouds: 'md-cloudy',Snow: 'md-snow',Drizzle: 'md-umbrella',} const phrases = { Default:{ title: "Fetchin the Weather",subtitle: "Be patient,you're witnessing a miracle",highlight: ["Fetchin"],color: "#636363",background: "#9C9C9C" },Clear: { title: "CLEAR.",subtitle: "You Better Go Outside",highlight: ["CLEAR"],color:"#E32500",background: "#FFD017" },Rain: { title: "It's Raining",subtitle: "You guessed it",highlight: ["Raining"],color:"#004A96",background:"#2F343A" },Thunderstorm: { title: "Not Just Raining,It's Storming",subtitle: "Free shower",highlight: ["Storming"],color:"#FBFF46",background:"#020202" },Clouds: { title: "Clouds for Days",subtitle: "Cotton candy skies",highlight: ["Days"],color:"#0044FF",background: "#939393" },Snow: { title: "Oh Yeah Bud. It's Snowin'",subtitle: "Make a snow angel bud",highlight: ["Snowin'"],color:"#021D4C",background:"#15A678" },Drizzle: { title: "Just a Wee Ol' Drizzle Lads",highlight: ["Wee","Ol'"],color:"#dbdbdb",background:"#1FBB68" },} class App extends Component { componentWillMount() { this.state = { temp: 0,weather: 'Default' } } componentDidMount() { this.getLocation() } getLocation() { navigator.geolocation.getCurrentPosition( posData => fetchWeather(posData.coords.latitude,posData.coords.longitude) .then(res => this.setState({ temp:Math.round(res.temp),weather: res.weather })),error => alert(error),{timeout: 10000} ) } render(){ console.log(this.state.weather) return( <View style={[styles.container,{backgroundColor: phrases[this.state.weather].background}]}> <StatusBar hidden={true}/> <View style={styles.header}> <Icon name={iconNames[this.state.weather]} size={80} color={'white'}/> <Text style={styles.temp}>{this.state.temp}°</Text> </View> <View style={styles.body}> <Highlight style={styles.title} highlightStyle={{color: phrases[this.state.weather].color}} searchWords={phrases[this.state.weather].highlight} textToHighlight={phrases[this.state.weather].title} /> <Text style={styles.subtitle}>{phrases[this.state.weather].subtitle}</Text> </View> </View> ) } } const styles = StyleSheet.create({ container: { flex:1,backgroundColor:'#FFD017' },header: { flexDirection:'row',alignItems:'center',justifyContent:'space-around',flex:1,},temp: { fontFamily: 'HelveticaNeue-Bold',fontSize: 45,color:'white' },body: { alignItems:'flex-start',justifyContent:'flex-end',flex:5,margin:10 },title: { fontFamily: 'HelveticaNeue-Bold',fontSize: 90,color:'white',marginBottom:5 },subtitle: { fontFamily: 'HelveticaNeue-Medium',fontSize: 16,color:'white' } }); AppRegistry.registerComponent('IsItRaining',() => App)
解决方法
fetch API不包含
any progress callbacks,因此您的选项要么使用
XMLHttpRequest,这在React Native中完全支持,要么是一个本质上将在其上构建的库.例如,您可以修改fetchWeather函数来执行以下操作:
export const fetchWeather = (lat,lon,progress) => { return new Promise((resolve,reject) => { const url = rootUrl+'&lat='+lat+'&lon='+lon+"&units=metric" console.log(url) var oReq = new XMLHttpRequest(); oReq.addEventListener("progress",progress); oReq.open('GET',url); oReq.send(); oReq.onreadystatechange = function() { if (oReq.readyState == XMLHttpRequest.DONE) { let data = JSON.parse(oReq.responseText); resolve({temp: data.main.temp,weather: json.weather[0].main}); } } }); }
进度是一个回调状态,您可以在其中更新状态.例如,在您的组件中,添加以下函数:
function updateProgress (oEvent) { if (oEvent.lengthComputable) { var progress = oEvent.loaded / oEvent.total; this.setState({progress}) } else { // Unable to compute progress information since the total size is unknown } }
然后,呼叫变为:
fetchWeather(posData.coords.latitude,posData.coords.longitude,this.updateProgress.bind(this)) fetchWeather(posData.coords.latitude,posData.coords.longitude)
该示例改编自MDN.