You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 00:15:05