atchain-mapbox-vue
Version:
A Vue 3 MapBox component library with subway lines, stations, markers and polygons support. Zero dependencies except Vue 3 and Mapbox GL JS.
70 lines (57 loc) • 1.8 kB
text/typescript
/**
* 数据获取工具函数
* 替代 axios 依赖,提供原生 fetch 实现
*/
export interface FetchOptions {
timeout?: number
retries?: number
retryDelay?: number
}
export interface DataFetcher {
(url: string, options?: FetchOptions): Promise<any>
}
/**
* 默认数据获取函数
*/
export const defaultDataFetcher: DataFetcher = async (url: string, options: FetchOptions = {}) => {
const {
timeout = 10000,
retries = 3,
retryDelay = 1000
} = options
const fetchWithTimeout = async (url: string, timeout: number): Promise<Response> => {
const controller = new AbortController()
const timeoutId = setTimeout(() => controller.abort(), timeout)
try {
const response = await fetch(url, {
signal: controller.signal,
headers: {
'Content-Type': 'application/json'
}
})
clearTimeout(timeoutId)
return response
} catch (error) {
clearTimeout(timeoutId)
throw error
}
}
let lastError: Error | null = null
for (let attempt = 0; attempt <= retries; attempt++) {
try {
const response = await fetchWithTimeout(url, timeout)
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`)
}
const data = await response.json()
return data
} catch (error) {
lastError = error as Error
if (attempt < retries) {
console.warn(`数据获取失败,${retryDelay}ms 后重试 (${attempt + 1}/${retries}):`, error)
await new Promise(resolve => setTimeout(resolve, retryDelay))
}
}
}
throw new Error(`数据获取失败,已重试 ${retries} 次: ${lastError?.message}`)
}