基于Google Maps API结果更新表格数据集的异步处理问题
问题解决步骤
1. 首先改造calculateDistance为Promise风格
你原来的calculateDistance是回调形式,没法直接用await调用,先修改为返回Promise的版本:
function calculateDistance(origin, destination) { return new Promise((resolve, reject) => { const google = window.google; const directionsService = new google.maps.DirectionsService(); directionsService.route( { origin: origin, destination: destination, travelMode: google.maps.TravelMode.DRIVING }, (result, status) => { if (status === google.maps.DirectionsStatus.OK) { resolve(result.routes[0].legs[0].distance.value); } else { console.error('Google Maps API error: ', status); resolve(Infinity); // 接口报错默认认为距离超出,可按业务需求调整处理逻辑 } } ); }) }
2. 修正过滤函数的语法错误
你之前写的const shouldRemoveContact = await(filters, contact) = () => {是语法错误,await只能在async函数内部使用,应该把这个函数声明为异步函数:
// 异步判断单个联系人是否需要被过滤 const shouldRemoveContact = async (filters, contact) => { for (const filter of filters) { if (filter.condition === 'equal' && contact[filter.field] != filter.value) { return true } if (filter.condition === 'max_10km') { const originAddress = `${contact['street']} ${contact['number']}, ${contact['zip']} ${contact['city']}, ${contact['country']}` const distance = await calculateDistance(originAddress, filter.value) return distance > 10000 } } return false } // 批量过滤所有联系人 async function filterContacts(filters, contacts) { // 并行计算所有联系人的过滤结果 const shouldRemoveList = await Promise.all( contacts.map(contact => shouldRemoveContact(filters, contact)) ) // 筛选出符合条件的联系人 return contacts.filter((_, index) => !shouldRemoveList[index]) }
3. 修正组件内的状态与副作用逻辑
调整useEffect的依赖项,避免无限渲染,等所有过滤逻辑执行完再更新状态:
const [filteredContacts, setFilteredContacts] = useState(contacts); const [isLoading, setIsLoading] = useState(false); // 表格直接使用filteredContacts即可,无需多余的useMemo封装 useEffect(() => { const runFilter = async () => { setIsLoading(true); const result = await filterContacts(clientFilter, contacts); setFilteredContacts(result); setIsLoading(false); } runFilter(); // 依赖项需要包含clientFilter和contacts,两者变化时自动重新过滤 }, [clientFilter, contacts]);
可选优化
如果联系人数量较多,Google Maps接口调用频率超限,可以把并行计算改成串行执行,或者给过滤器参数增加防抖逻辑,避免参数频繁变动时重复发起请求。
内容的提问来源于stack exchange,提问作者PennyWise
相关产品推荐
相关产品推荐

