在 RN 中获取当前用户坐标的最佳方法是什么
What is the best way to make function for getting current user coordinates in RN
我想创建一个获取用户坐标的函数,但我发现我不确定我的方法是否足够好。
我想知道其他人如何编写此函数以在 ios 和 android.
上 100% 确定地工作
现在我有这样的东西:
function getUserLocation(callback: func) {
Permissions.check('location')
.then(response => {
if (response == 'authorized') {
navigator.geolocation.getCurrentPosition(
(location) => {
callback({
latitude: location.coords.latitude,
longitude: location.coords.longitude
}, response);
},
(error) => {
callback(null);
},
Platform.OS === 'android' ? null : {enableHighAccuracy: true, timeout: 100000, maximumAge: 1000}
);
} else {
callback(null, response);
}
})
}
所以你可以看到我想使用这个函数,这样调用者就可以知道是否允许使用位置以及是否获取当前坐标。
我正在尝试的是学习如何:
1. 使这样的函数成为 awaitable.
2. 其他人如何实现这样的功能(OS)并且工作 100% 相同。
你的问题分为两部分
1. Make function like this to be awaitable.
这可以通过向您提供如何操作的逻辑来直接回答。 Awaitable 只不过是一个异步函数或 return 承诺的东西。如果你想要 async
方式,那么你需要先制作一个 getCurrentPosition
的版本,return 是一个承诺。可以像下面那样完成
function getCurrentLocation(options) {
return new Promise((resolve, reject) => {
navigator.geolocation.getCurrentPosition(resolve, ({code, message}) =>
reject(Object.assign(new Error(message), {name: "PositionError", code})),
options);
});
};
PS:感谢 以上代码
现在您可以像下面这样重写代码
async function getUserLocation() {
let response = await Permissions.check('location')
let options = Platform.OS === 'android' ? null : {enableHighAccuracy: true, timeout: 100000, maximumAge: 1000}
if (response == 'authorized') {
return await getCurrentLocation(options)
}
return null;
}
如果你不想走promise
的路,它会像下面这样
function getUserLocation() {
return new Promise((resolve, reject) => {
Permissions.check('location')
.then(response => {
if (response == 'authorized') {
navigator.geolocation.getCurrentPosition(
(location) => {
resolve({
latitude: location.coords.latitude,
longitude: location.coords.longitude
});
},
(error) => {
reject(error);
},
Platform.OS === 'android' ? null : { enableHighAccuracy: true, timeout: 100000, maximumAge: 1000 }
);
} else {
resolve(null);
}
})
});
}
这里的一个关键点与回调不同,承诺解析单个值,这意味着您需要使用对象来 return 多个参数。
2. How others make function like this (for both OS) and to work 100% same.
这是你的问题变得固执己见的地方,我可能会采取一些不同的方法,你可能会做其他事情,而另一个人可能会做完全不同的事情。但我仍将讨论几种可能性。
拆分为多个函数
function getUserLocation() {
if (Platform.OS === 'android')
{
return getUserLocationAndroid();
} else {
return getUserLocationIOS();
}
}
维护键值对
您可以拥有基于 OS.
自动绑定函数的代码
Utils = {
getFunction(name) {
if ((name + Platform.OS) in this)
return this[name + Platform.OS]
return this[name];
}
getLocation: function() {}
//getLocationandroid: function() {}
}
因此,默认情况下,您将 getLocation
用于服务器 OS,但如果 OS 代码之一偏离太多,您将为相同的代码创建一个新函数。代码如下所示
Utils.getFunction("getLocation")(...)
一个带分支的函数
这就是您目前的做法。只要功能易于理解并且有明确的意图,我会坚持使用代码的哪一部分执行特定于平台的内容
这里可能还有 10 多种不同的方法,但最终取决于一件事,哪种更容易维护、理解使用。有些方法也是特定于用例的,您可以根据用例混合使用多种方法
总的来说,对我来说这种方法不是最好的方法。有什么理由要拉吗?
两者 OS 都有一个推送模式,你可以根据位置的变化跟踪位置,这对用户的电池寿命和你的应用程序必须做的处理来说更好。此外,使某些东西可用将是一个阻塞调用的事情,你不会真的想做很多事情。
React Native 有方法navigator.geolocation.watchPosition
你可以找一个参考[=13=]。您可以定义有关准确性、超时等的选项。
下一个函数用于 redux 的情况,因此 redux-thunk 每次都会发送事件作为承诺,以重新计算 reducer 中的状态,但可以通过修改回调函数来轻松适应,以执行您想要的任何其他操作。
let geolocationSettings = {enableHighAccuracy: true, timeout: 5000, maximum: 5000, distanceFilter:10}
function setPositionWatch(dispatch,geolocationSettings){
positionWatcher = navigator.geolocation.watchPosition(
(pos) => {
dispatch({
type: types.NEW_POSITION,
state: pos
})
},
() => {
dispatch({
type: types.ERROR_POSITION
})
},
geolocationSettings)
}
基本上,您为这种推送机制提供正确行为、错误行为和选项的回调。当您想停止收集位置信息时,您可以执行 clearWatch
.
制作 getCurrentPosition
的异步版本,您可以将此功能添加到 navigator.geolocation。
async function getCurrentPosition(options) {
return new Promise((resolve, reject) => {
navigator.geolocation.getCurrentPosition(
position => resolve(position.coords),
error => reject(error),
options
});
});
}
下一个函数就是你想要的。最好在未授权时抛出异常,因为无论如何你需要 try / catch 因为 getCurrentPosition
.
const locationOptions = Platform.OS === 'android' ? null :
{ enableHighAccuracy: true, timeout: 100000, maximumAge: 1000 };
async function getUserLocation() {
let permission = await Permissions.check('location');
if (permission !== 'authorized') {
throw new Error('Not authorized: ' + permission);
}
return await getCurrentPosition(locationOptions);
}
使用方法:
try {
let location = await getUserLocation(); // { latitude, longitude }
} catch (error) {
Alert.alert(error.message);
}
我想创建一个获取用户坐标的函数,但我发现我不确定我的方法是否足够好。
我想知道其他人如何编写此函数以在 ios 和 android.
上 100% 确定地工作
现在我有这样的东西:
function getUserLocation(callback: func) {
Permissions.check('location')
.then(response => {
if (response == 'authorized') {
navigator.geolocation.getCurrentPosition(
(location) => {
callback({
latitude: location.coords.latitude,
longitude: location.coords.longitude
}, response);
},
(error) => {
callback(null);
},
Platform.OS === 'android' ? null : {enableHighAccuracy: true, timeout: 100000, maximumAge: 1000}
);
} else {
callback(null, response);
}
})
}
所以你可以看到我想使用这个函数,这样调用者就可以知道是否允许使用位置以及是否获取当前坐标。
我正在尝试的是学习如何:
1. 使这样的函数成为 awaitable.
2. 其他人如何实现这样的功能(OS)并且工作 100% 相同。
你的问题分为两部分
1. Make function like this to be awaitable.
这可以通过向您提供如何操作的逻辑来直接回答。 Awaitable 只不过是一个异步函数或 return 承诺的东西。如果你想要 async
方式,那么你需要先制作一个 getCurrentPosition
的版本,return 是一个承诺。可以像下面那样完成
function getCurrentLocation(options) {
return new Promise((resolve, reject) => {
navigator.geolocation.getCurrentPosition(resolve, ({code, message}) =>
reject(Object.assign(new Error(message), {name: "PositionError", code})),
options);
});
};
PS:感谢 以上代码
现在您可以像下面这样重写代码
async function getUserLocation() {
let response = await Permissions.check('location')
let options = Platform.OS === 'android' ? null : {enableHighAccuracy: true, timeout: 100000, maximumAge: 1000}
if (response == 'authorized') {
return await getCurrentLocation(options)
}
return null;
}
如果你不想走promise
的路,它会像下面这样
function getUserLocation() {
return new Promise((resolve, reject) => {
Permissions.check('location')
.then(response => {
if (response == 'authorized') {
navigator.geolocation.getCurrentPosition(
(location) => {
resolve({
latitude: location.coords.latitude,
longitude: location.coords.longitude
});
},
(error) => {
reject(error);
},
Platform.OS === 'android' ? null : { enableHighAccuracy: true, timeout: 100000, maximumAge: 1000 }
);
} else {
resolve(null);
}
})
});
}
这里的一个关键点与回调不同,承诺解析单个值,这意味着您需要使用对象来 return 多个参数。
2. How others make function like this (for both OS) and to work 100% same.
这是你的问题变得固执己见的地方,我可能会采取一些不同的方法,你可能会做其他事情,而另一个人可能会做完全不同的事情。但我仍将讨论几种可能性。
拆分为多个函数
function getUserLocation() {
if (Platform.OS === 'android')
{
return getUserLocationAndroid();
} else {
return getUserLocationIOS();
}
}
维护键值对
您可以拥有基于 OS.
自动绑定函数的代码Utils = {
getFunction(name) {
if ((name + Platform.OS) in this)
return this[name + Platform.OS]
return this[name];
}
getLocation: function() {}
//getLocationandroid: function() {}
}
因此,默认情况下,您将 getLocation
用于服务器 OS,但如果 OS 代码之一偏离太多,您将为相同的代码创建一个新函数。代码如下所示
Utils.getFunction("getLocation")(...)
一个带分支的函数
这就是您目前的做法。只要功能易于理解并且有明确的意图,我会坚持使用代码的哪一部分执行特定于平台的内容
这里可能还有 10 多种不同的方法,但最终取决于一件事,哪种更容易维护、理解使用。有些方法也是特定于用例的,您可以根据用例混合使用多种方法
总的来说,对我来说这种方法不是最好的方法。有什么理由要拉吗?
两者 OS 都有一个推送模式,你可以根据位置的变化跟踪位置,这对用户的电池寿命和你的应用程序必须做的处理来说更好。此外,使某些东西可用将是一个阻塞调用的事情,你不会真的想做很多事情。
React Native 有方法navigator.geolocation.watchPosition
你可以找一个参考[=13=]。您可以定义有关准确性、超时等的选项。
下一个函数用于 redux 的情况,因此 redux-thunk 每次都会发送事件作为承诺,以重新计算 reducer 中的状态,但可以通过修改回调函数来轻松适应,以执行您想要的任何其他操作。
let geolocationSettings = {enableHighAccuracy: true, timeout: 5000, maximum: 5000, distanceFilter:10}
function setPositionWatch(dispatch,geolocationSettings){
positionWatcher = navigator.geolocation.watchPosition(
(pos) => {
dispatch({
type: types.NEW_POSITION,
state: pos
})
},
() => {
dispatch({
type: types.ERROR_POSITION
})
},
geolocationSettings)
}
基本上,您为这种推送机制提供正确行为、错误行为和选项的回调。当您想停止收集位置信息时,您可以执行 clearWatch
.
制作 getCurrentPosition
的异步版本,您可以将此功能添加到 navigator.geolocation。
async function getCurrentPosition(options) {
return new Promise((resolve, reject) => {
navigator.geolocation.getCurrentPosition(
position => resolve(position.coords),
error => reject(error),
options
});
});
}
下一个函数就是你想要的。最好在未授权时抛出异常,因为无论如何你需要 try / catch 因为 getCurrentPosition
.
const locationOptions = Platform.OS === 'android' ? null :
{ enableHighAccuracy: true, timeout: 100000, maximumAge: 1000 };
async function getUserLocation() {
let permission = await Permissions.check('location');
if (permission !== 'authorized') {
throw new Error('Not authorized: ' + permission);
}
return await getCurrentPosition(locationOptions);
}
使用方法:
try {
let location = await getUserLocation(); // { latitude, longitude }
} catch (error) {
Alert.alert(error.message);
}