news 2026/4/15 17:07:08

鸿蒙应用的网络请求和数据处理:从HTTP到本地缓存的完整方案

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
鸿蒙应用的网络请求和数据处理:从HTTP到本地缓存的完整方案

网络请求是现代应用的核心功能。无论是获取用户数据、上传文件还是实时通信,都需要与服务器进行网络交互。但网络请求涉及许多复杂的问题:网络延迟、错误处理、数据缓存、离线支持等。

本文将为你讲解如何在鸿蒙应用中优雅地处理网络请求和数据,包括HTTP请求、JSON解析、错误处理、数据缓存等。通过学习这些内容,你将能够构建更加健壮和高效的网络层。

HTTP请求的基础实现

鸿蒙提供了http模块来进行HTTP请求。基础的HTTP请求实现相对简单,但要做好错误处理和超时控制。

基础GET请求

importhttpfrom'@ohos.net.http'asyncfunctionfetchData(url:string):Promise<string>{lethttpRequest=http.createHttpRequest()try{awaithttpRequest.request(url,{method:http.RequestMethod.GET,connectTimeout:10000,readTimeout:10000})letresult=httpRequest.getResponseBody()returnresultasstring}catch(error){console.error('Request failed:',error)throwerror}finally{httpRequest.destroy()}}

POST请求和请求头

asyncfunctionpostData(url:string,data:object):Promise<string>{lethttpRequest=http.createHttpRequest()try{awaithttpRequest.request(url,{method:http.RequestMethod.POST,header:{'Content-Type':'application/json','Authorization':'Bearer token'},extraData:JSON.stringify(data),connectTimeout:10000,readTimeout:10000})letresult=httpRequest.getResponseBody()returnresultasstring}catch(error){console.error('Request failed:',error)throwerror}finally{httpRequest.destroy()}}

JSON数据解析

从服务器获取的数据通常是JSON格式。正确的JSON解析对于数据处理至关重要。

基础JSON解析

interfaceUser{id:numbername:stringemail:string}asyncfunctionfetchUser(userId:number):Promise<User>{letresponse=awaitfetchData(`https://api.example.com/users/${userId}`)letuser=JSON.parse(response)asUserreturnuser}

处理复杂的JSON结构

interfacePost{id:numbertitle:stringcontent:stringauthor:User comments:Comment[]}interfaceComment{id:numbertext:stringauthor:User}asyncfunctionfetchPost(postId:number):Promise<Post>{letresponse=awaitfetchData(`https://api.example.com/posts/${postId}`)letpost=JSON.parse(response)asPostreturnpost}

JSON序列化

functionserializeUser(user:User):string{returnJSON.stringify(user)}functionserializeUsers(users:User[]):string{returnJSON.stringify(users,null,2)}

错误处理和重试机制

网络请求经常会失败。实现良好的错误处理和重试机制可以提高应用的稳定性。

基础错误处理

enumRequestError{NETWORK_ERROR='NETWORK_ERROR',TIMEOUT='TIMEOUT',SERVER_ERROR='SERVER_ERROR',PARSE_ERROR='PARSE_ERROR'}classRequestExceptionextendsError{constructor(publiccode:RequestError,message:string){super(message)}}asyncfunctionfetchDataWithErrorHandling(url:string):Promise<string>{try{lethttpRequest=http.createHttpRequest()awaithttpRequest.request(url,{method:http.RequestMethod.GET,connectTimeout:10000,readTimeout:10000})letstatusCode=httpRequest.getResponseCode()if(statusCode>=400){thrownewRequestException(RequestError.SERVER_ERROR,`Server error:${statusCode}`)}returnhttpRequest.getResponseBody()asstring}catch(error){if(errorinstanceofRequestException){throwerror}thrownewRequestException(RequestError.NETWORK_ERROR,'Network request failed')}}

重试机制

asyncfunctionfetchDataWithRetry(url:string,maxRetries:number=3):Promise<string>{letlastError:Error|null=nullfor(leti=0;i<maxRetries;i++){try{returnawaitfetchDataWithErrorHandling(url)}catch(error){lastError=errorasErrorif(i<maxRetries-1){// 指数退避:等待时间随着重试次数增加而增加letdelay=Math.pow(2,i)*1000awaitnewPromise(resolve=>setTimeout(resolve,delay))}}}throwlastError}

数据缓存策略

频繁的网络请求会浪费带宽和电池电量。实现合理的缓存策略可以显著提升应用性能。

内存缓存

classMemoryCache<T>{privatecache:Map<string,{data:T,timestamp:number}>=newMap()privatettl:number// 缓存过期时间(毫秒)constructor(ttl:number=5*60*1000){this.ttl=ttl}set(key:string,data:T):void{this.cache.set(key,{data,timestamp:Date.now()})}get(key:string):T|null{letitem=this.cache.get(key)if(!item){returnnull}if(Date.now()-item.timestamp>this.ttl){this.cache.delete(key)returnnull}returnitem.data}clear():void{this.cache.clear()}}letuserCache=newMemoryCache<User>(10*60*1000)asyncfunctionfetchUserWithCache(userId:number):Promise<User>{letcacheKey=`user_${userId}`// 检查缓存letcachedUser=userCache.get(cacheKey)if(cachedUser){returncachedUser}// 从网络获取letuser=awaitfetchUser(userId)// 存入缓存userCache.set(cacheKey,user)returnuser}

本地存储缓存

importpreferencesfrom'@ohos.data.preferences'classPersistentCache{privatepreferences:preferences.Preferences|null=nullasyncinit(context:any):Promise<void>{this.preferences=awaitpreferences.getPreferences(context,'app_cache')}asyncset(key:string,value:string):Promise<void>{if(!this.preferences){thrownewError('Cache not initialized')}awaitthis.preferences.put(key,value)awaitthis.preferences.flush()}asyncget(key:string):Promise<string|null>{if(!this.preferences){thrownewError('Cache not initialized')}letvalue=awaitthis.preferences.get(key,null)returnvalueasstring|null}asyncremove(key:string):Promise<void>{if(!this.preferences){thrownewError('Cache not initialized')}awaitthis.preferences.delete(key)awaitthis.preferences.flush()}}letpersistentCache=newPersistentCache()asyncfunctionfetchUserWithPersistentCache(userId:number):Promise<User>{letcacheKey=`user_${userId}`// 检查本地缓存letcachedData=awaitpersistentCache.get(cacheKey)if(cachedData){returnJSON.parse(cachedData)asUser}// 从网络获取letuser=awaitfetchUser(userId)// 存入本地缓存awaitpersistentCache.set(cacheKey,JSON.stringify(user))returnuser}

离线支持

应用应该能够在网络不可用时继续工作。实现离线支持需要合理的缓存策略和用户提示。

检查网络连接

importconnectionfrom'@ohos.net.connection'asyncfunctionisNetworkAvailable():Promise<boolean>{try{letnetHandle=awaitconnection.getDefaultNetConnection()letnetCapabilities=awaitconnection.getNetCapabilities(netHandle)returnnetCapabilities.hasCapability(connection.NetCapsType.NET_CAPABILITY_INTERNET)}catch(error){returnfalse}}asyncfunctionfetchDataWithOfflineSupport(url:string):Promise<string>{letisOnline=awaitisNetworkAvailable()if(isOnline){try{returnawaitfetchDataWithRetry(url)}catch(error){// 网络请求失败,尝试使用缓存letcachedData=awaitpersistentCache.get(url)if(cachedData){console.warn('Using cached data due to network error')returncachedData}throwerror}}else{// 离线模式,使用缓存letcachedData=awaitpersistentCache.get(url)if(cachedData){returncachedData}thrownewError('No network connection and no cached data available')}}

最佳实践

使用拦截器统一处理请求

classHttpClient{privaterequestInterceptors:Array<(config:any)=>any>=[]privateresponseInterceptors:Array<(response:any)=>any>=[]addRequestInterceptor(interceptor:(config:any)=>any):void{this.requestInterceptors.push(interceptor)}addResponseInterceptor(interceptor:(response:any)=>any):void{this.responseInterceptors.push(interceptor)}asyncrequest(url:string,config:any={}):Promise<any>{// 执行请求拦截器for(letinterceptorofthis.requestInterceptors){config=interceptor(config)}// 执行请求letresponse=awaitfetchDataWithRetry(url)// 执行响应拦截器for(letinterceptorofthis.responseInterceptors){response=interceptor(response)}returnresponse}}lethttpClient=newHttpClient()// 添加认证拦截器httpClient.addRequestInterceptor((config)=>{config.header=config.header||{}config.header['Authorization']='Bearer token'returnconfig})// 添加日志拦截器httpClient.addResponseInterceptor((response)=>{console.log('Response:',response)returnresponse})

分离数据层和UI层

classUserRepository{asyncgetUser(userId:number):Promise<User>{returnawaitfetchUserWithPersistentCache(userId)}asyncgetUsers(page:number,pageSize:number):Promise<User[]>{leturl=`https://api.example.com/users?page=${page}&pageSize=${pageSize}`letresponse=awaitfetchDataWithOfflineSupport(url)returnJSON.parse(response)asUser[]}}@Component struct UserList{@State users:User[]=[]@State loading:boolean=false@State error:string=''privaterepository=newUserRepository()asyncloadUsers(){this.loading=truetry{this.users=awaitthis.repository.getUsers(1,20)}catch(error){this.error=(errorasError).message}finally{this.loading=false}}build(){Column(){if(this.loading){LoadingProgress()}elseif(this.error){Text(this.error)}else{List(){ForEach(this.users,(user:User)=>{ListItem(){Text(user.name)}})}}}}}

总结

网络请求和数据处理是应用开发的核心。通过实现良好的错误处理、缓存策略和离线支持,你可以构建更加健壮和高效的应用。

关键要点包括:

  • 使用正确的HTTP方法和请求头
  • 实现完善的错误处理和重试机制
  • 合理使用内存缓存和本地存储缓存
  • 支持离线模式
  • 分离数据层和UI层

现在就在你的项目中应用这些最佳实践吧。如果你有任何问题或想法,欢迎在评论区分享。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/11 19:44:44

看病(信息学奥赛一本通- P1371)

【题目描述】有个朋友在医院工作&#xff0c;想请BSNY帮忙做个登记系统。具体是这样的&#xff0c;最近来医院看病的人越来越多了&#xff0c;因此很多人要排队&#xff0c;只有当空闲时放一批病人看病。但医院的排队不同其他排队&#xff0c;因为多数情况下&#xff0c;需要病…

作者头像 李华
网站建设 2026/4/13 16:20:29

从零开始搞懂时间/空间复杂度 + 图解三指针合并有序数组(力扣88题)

一、什么是时间复杂度和空间复杂度&#xff1f;——用5段代码讲明白在算法世界里&#xff0c;我们不只关心“能不能跑通”&#xff0c;更关心“跑得快不快”、“占不占地方”。这就是时间复杂度和空间复杂度要解决的问题。时间复杂度&#xff1a;衡量“执行步骤”的增长趋势不是…

作者头像 李华
网站建设 2026/4/13 15:48:46

9 个高效降AI工具推荐,本科生必备!

9 个高效降AI工具推荐&#xff0c;本科生必备&#xff01; AI降重工具&#xff1a;让论文更自然&#xff0c;让学术更纯粹 在当今高校教育中&#xff0c;AI生成内容&#xff08;AIGC&#xff09;已经成为论文写作中不可忽视的一部分。然而&#xff0c;随着各大高校对AI痕迹的审…

作者头像 李华
网站建设 2026/4/13 19:18:28

为什么90%的脱敏系统无法控制恢复?:Open-AutoGLM给出答案

第一章&#xff1a;为什么90%的脱敏系统无法控制恢复&#xff1f; 数据脱敏的核心目标是在保护敏感信息的同时&#xff0c;保留数据的可用性。然而&#xff0c;绝大多数脱敏系统在设计时忽略了“可逆性控制”这一关键维度&#xff0c;导致脱敏后的数据可能被恶意还原&#xff0…

作者头像 李华
网站建设 2026/4/15 6:57:36

【Open-AutoGLM异常预警实战指南】:3大核心机制揭秘企业级访问行为监控

第一章&#xff1a;Open-AutoGLM访问行为异常预警概述Open-AutoGLM 是一个基于自动化生成语言模型的开放平台&#xff0c;广泛应用于智能客服、内容生成与代码辅助等场景。随着接入系统的增多&#xff0c;平台面临日益复杂的访问行为&#xff0c;其中包含潜在的恶意请求、高频爬…

作者头像 李华
网站建设 2026/4/4 2:50:32

【专家亲授】Open-AutoGLM隐私保护实战:4个关键审计日志分析技巧

第一章&#xff1a;Open-AutoGLM隐私数据访问审计概述在人工智能系统日益依赖大规模数据训练的背景下&#xff0c;Open-AutoGLM作为一款开源的自动推理语言模型框架&#xff0c;其对隐私数据的处理机制成为安全合规的核心关注点。隐私数据访问审计旨在追踪、记录并分析系统中敏…

作者头像 李华