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

求助:Angular+RxJS实现Esri Feature Layer查询/编辑的VPN断连重试

问题分析与解决方案

你当前的重试逻辑无效,核心原因是from(testFeatureLayer.queryFeatures(query))将Promise转为Observable后,这个Promise只会执行一次——重试时只是重复之前失败的结果,不会重新发起Feature Layer的查询请求。


基础修复方案:用defer确保每次重试重新发起请求

使用RxJS的defer操作符包装查询调用,它会在每次Observable被订阅(包括重试场景)时,重新执行传入的工厂函数,从而重新发起queryFeatures请求。

import { defer, throwError } from 'rxjs';
import { retry, catchError } from 'rxjs/operators';

const testFeatureLayer = new FeatureLayer({ url: LAYERDETAILS.TEST.url });
const query = testFeatureLayer.createQuery();
query.where = '1=1';
query.outFields = ['*'];

// 用defer包装查询逻辑,每次重试都会重新执行queryFeatures
defer(() => testFeatureLayer.queryFeatures(query)).pipe(
  retry({
    count: 50,
    delay: 1000,
    resetOnSuccess: true
  }),
  catchError((error) => {
    console.error('所有重试失败:', error);
    return throwError(() => error);
  })
).subscribe({
  next: (response) => {
    console.log('查询响应:', response);
  },
  error: (error) => {
    console.error('最终错误:', error);
  }
});

进阶优化:结合VPN/网络状态触发重试

如果希望只在VPN重新连接(网络恢复)后才重试,可以监听浏览器的网络状态事件,配合retryWhen实现更精准的重试逻辑:

import { defer, throwError, fromEvent, timer } from 'rxjs';
import { retryWhen, mergeMap, catchError } from 'rxjs/operators';

// 监听网络恢复事件,延迟1秒确保VPN连接稳定
const online$ = fromEvent(window, 'online').pipe(
  mergeMap(() => timer(1000))
);

defer(() => testFeatureLayer.queryFeatures(query)).pipe(
  retryWhen(errors => 
    errors.pipe(
      mergeMap((error, index) => {
        // 限制最大重试次数
        if (index < 50) {
          console.log(`等待网络恢复后重试,当前次数: ${index+1}`);
          return online$; // 仅当网络恢复时才重试
        }
        return throwError(() => new Error('超过最大重试次数'));
      })
    )
  ),
  catchError((error) => {
    console.error('所有重试失败:', error);
    return throwError(() => error);
  })
).subscribe({
  next: (response) => {
    console.log('查询响应:', response);
  },
  error: (error) => {
    console.error('最终错误:', error);
  }
});

编辑操作的适配

对于Esri Feature Layer的编辑操作(如applyEdits),同样可以用defer包装,确保每次重试都重新发起编辑请求:

defer(() => testFeatureLayer.applyEdits(edits)).pipe(
  // 复用上述重试逻辑
);

内容的提问来源于stack exchange,提问作者Fatih Enes

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 05:42:34