我希望得到我的任务的距离,这是具有lat lng值的对象。它们保存在我的firebase数据库中。
现在我的问题是,我通过setState在componentWillMount中设置用户的当前位置。但是当我从异步任务(firebase查询)调用getDistance时,用户当前位置的状态为null。
我认为这是因为操作不在同一个上下文中。所以我试着深入研究redux,但却无法掌握这个话题。
我怎么解决这个问题?
getDistance(latitude, longitude) {
let c = geolib.getDistance(
{ latitude: { latitude }, longitude: { longitude } }, // strawa
{ latitude: this.state.latitude, longitude: this.state.longitude }, // sbg
100,
1
);
return c / 1000;
//alert(c / 1000); // 25km
}
/*
Get the Users current location
iOS -> asks only one time for permission, so pay atention if disabled !!!
*/
getCurrentLocation() {
var loc;
navigator.geolocation.getCurrentPosition(
position => {
console.log("Location Request - Position = " + position);
this.setState({
latitude: position.coords.latitude,
longitude: position.coords.longitude
});
},
error => this.setState({ error: error.message }),
{ enableHighAccuracy: false, timeout: 200000, maximumAge: 1000 }
);
}
componentWillMount() {
//this.getCurrentLocation();
this.listenForTasks(this.tasksRef);
}
listenForTasks(tasksRef) {
tasksRef.on("value", snap => {
var tasks = [];
snap.forEach(child => {
// If Task_Type = 0 getDistance
var distance = "";
if (child.val().type === "0") {
distance = this.getDistance(child.val().lat, child.val().lng);
} else {
distance = "Online";
}
tasks.push({
title: child.val().title,
budget: child.val().budget,
offersCount: child.val().offersCount,
commentsCount: child.val().commentsCount,
distance: distance
});
});
tasks.reverse();
this.setState({
dataSource: this.state.dataSource.cloneWithRows(tasks)
});
});
}
这是我尝试以非常简单的方式实现redux的不好尝试,但是我收到了一个错误:"预期的监听器是一个函数"
import { createStore } from "redux";
const reducer = (state = [], action) => {
if (action.type === "getCurrentLocation") {
return action.payload;
}
return state;
};
const store = createStore(reducer);
class TaskBrowseScreen extends React.Component {
constructor(props) {
super(props);
store.dispatch({ type: "getCurrentLocation", payload: "?" });
store.subscribe();
...
答案 0 :(得分:-1)
首先,您不应该在componentWillMount
=>中执行此操作。 why? manual
您的问题出现是因为您没有连结来电。最好在设置getDistance
的位置后调用geolocation
:
最简单的方法是返回一个承诺:
constructor() {
super();
this.getCurrentLocation().then(() => {
this.listenForTasks();
});
}
getCurrentLocation() {
let resolver;
let rejector;
const promise = new Promise((resolve, reject) => {
resolver = resolve;
rejector = reject;
});
var loc;
navigator.geolocation.getCurrentPosition(
position => {
console.log("Location Request - Position = " + position);
this.setState({
latitude: position.coords.latitude,
longitude: position.coords.longitude
}, resolver);
},
error => this.setState({ error: error.message }, rejector),
{ enableHighAccuracy: false, timeout: 200000, maximumAge: 1000 }
);
return promise;
}
UPD:
它对你来说可能很重要,不要花时间将所有异步方法一个接一个地链接到期望中。在你致电getDistance
之前,你可以存储承诺并建立一个链:
constructor() {
super();
this._promise = this.getCurrentLocation();
this.listenForTasks();
}
listenForTasks() {
// some async
this._promise.then(() => {
this.getDistance();
});
}
您可能不会花时间并且并行调用db.call。