如何在地理定位Promise封装中处理特定错误码?
地理定位API封装(内置全量错误处理)
原实现核心问题
之前标记为async的函数没有真正等待定位异步流程完成:geo.getCurrentPosition是基于回调的异步API,调用后会立刻执行后续函数代码,由于没有把回调结果和Promise状态绑定,函数会直接返回resolved的空结果,最终导致then里的onSave提前触发。
完整封装实现
封装时将所有成功格式化、错误码判断逻辑全部放到Promise内部,外层不需要接收原生的GeolocationAPI对象,也不需要额外判断错误类型:
const fetchGeoLocation: SearchService["fetchGeoLocation"] = () => { // 同步做能力检测,不满足直接返回拒绝状态的Promise const geo = navigator.geolocation; if (!geo) { return Promise.reject(new Error("error.geolocation-unavailable")); } // 手动构建Promise,接管所有原生回调逻辑 return new Promise((resolve, reject) => { // 内置所有错误处理逻辑,直接抛出标准化错误 const handleError = (err: GeolocationPositionError) => { if (err.code === 1) reject(new Error("error.geolocation-permission_denied")); if (err.code === 2) reject(new Error("error.geolocation-unavailable")); if (err.code === 3) reject(new Error("error.geolocation-timeout")); }; // 内置成功逻辑,直接返回格式化后的业务数据 const handleSuccess = (position: GeolocationPosition) => { resolve({ data: { location: [position.coords.longitude, position.coords.latitude] } }); }; // 沿用原有的定位配置参数,保持原有行为不变 geo.getCurrentPosition(handleSuccess, handleError, { maximumAge: 10000 }); }); };
调用侧极简写法
封装完成后,外部调用不需要处理任何原生定位的错误码逻辑,只需要拿标准化的结果和错误信息即可:
const onUpdateLocation = async () => { onLoad(); try { const res = await fetchGeoLocation(); onSave(res.data); } catch ({ message }) { // 拿到的就是已经映射完成的错误提示文案 onError(message); } }; // 也可以用链式Promise写法,效果完全一致 // fetchGeoLocation() // .then((res) => onSave(res.data)) // .catch(({ message }) => onError(message));
实现优化点
- 移除了原函数不必要的
async标记:整个函数返回的就是手动创建的Promise,不需要async语法糖,避免多余的Promise层级封装 - 能力检测逻辑放在Promise外部同步执行:不符合条件时可以更早触发错误,减少不必要的Promise实例创建开销
- 替换了原有的
any类型标注:使用浏览器内置的GeolocationPosition、GeolocationPositionError类型,获得完整的类型提示,减少类型报错 - 完全保留原有的定位配置(10秒的结果缓存时长),不会改变原有定位逻辑的行为
内容的提问来源于stack exchange,提问作者HelloWorldEngineer
相关产品推荐
相关产品推荐

