求助: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
相关产品推荐
相关产品推荐

