HarmonyOS Base64Util 同步 vs 异步:六个方法该怎么选?
文章目录前言一、同步版本解析encodeSyncencodeToStrSyncdecodeSync二、异步版本解析encodeencodeToStrdecode三、Demo 中的四种组合四、选型矩阵五、关于 util.Type 参数六、常见踩坑踩坑1同步方法在大文件上卡 UI踩坑2解码失败没有 try-catch踩坑3混用编码类型七、总结前言近期发现一款很有意思的HarmonyOS 三方库, 地址 pura/harmony-utils(V1.4.0) , 作者是桃花镇童长老, 我这里也是直接通过该作者公布的源码进行案例编写进行,写了到目前写了一部分demo ,感觉确实很有帮助,这里呢也是开始写一个系列的演示demo 供大家参考。如有帮助可以在OpenHarmony中进行下载安装进行使用哦案例demo导航展示↓↓↓↓↓↓接下来言归正传 ↓↓↓↓Base64Util 有 6 个方法其中同步 3 个、异步 3 个一一对应encode ↔ encodeSync encodeToStr ↔ encodeToStrSync decode ↔ decodeSync很多人看到有异步就直接用异步看到有同步就觉得同步方便直接用同步。但这两种选法都不严谨。正确的做法是根据数据量大小和调用场景来选。一、同步版本解析encodeSyncstaticencodeSync(array:Uint8Array):Uint8Array{constbase64newutil.Base64Helper();constresultbase64.encodeSync(array);returnresult;}特点直接返回值不需要await在当前线程执行会阻塞主线程适合小数据量几KB以内encodeToStrSyncstaticencodeToStrSync(array:Uint8Array,options?:util.Type):string{constbase64newutil.Base64Helper();constresultbase64.encodeToStringSync(array,options);returnresult;}最常用的同步方法直接返回 Base64 字符串不需要await不需要转换拿来即用。decodeSyncstaticdecodeSync(array:Uint8Array|string,options?:util.Type):Uint8Array{constbase64newutil.Base64Helper();constresultbase64.decodeSync(array,options);returnresult;}接受Uint8Array或stringBase64 字符串直接返回Uint8Array。二、异步版本解析encodestaticencode(array:Uint8Array):PromiseUint8Array{constbase64newutil.Base64Helper();returnbase64.encode(array);}返回PromiseUint8Array必须用await或.then()处理结果。encodeToStrstaticencodeToStr(array:Uint8Array,options?:util.Type):Promisestring{constbase64newutil.Base64Helper();returnbase64.encodeToString(array,options);}最常用的异步方法返回Promisestring适合大文件编码或在 async 函数中调用。decodestaticdecode(array:Uint8Array|string,options?:util.Type):PromiseUint8Array{constbase64newutil.Base64Helper();returnbase64.decode(array,options);}三、Demo 中的四种组合Base64DemoPage.ets演示了所有四种编解码组合asyncrunEncode(){constrawthis.textToUint8Array(this.inputText);this.addLog(输入,原文长度:${raw.length}字节,info);if(this.syncMode){// 同步模式if(this.toStrMode){// 组合一同步编码 → 字符串constencodedBase64Util.encodeToStrSync(raw);constdecodedRawBase64Util.decodeSync(encoded);constdecodedthis.uint8ArrayToText(decodedRaw);this.results[{label:encodeToStrSync,value:encoded,byteLen:raw.length},{label:decodeSync→Str,value:decoded,byteLen:decoded.length},];this.addLog(Sync,encodeToStrSync decodeSync 完成,success);}else{// 组合二同步编码 → Uint8ArrayconstencodedBase64Util.encodeSync(raw);constdecodedBase64Util.decodeSync(encoded);this.results[{label:encodeSync (Uint8Array),value:this.uint8ArrayToText(encoded),byteLen:raw.length},{label:decodeSync (Uint8Array),value:this.uint8ArrayToText(decoded),byteLen:decoded.length},];this.addLog(Sync,encodeSync decodeSync 完成,success);}}else{// 异步模式if(this.toStrMode){// 组合三异步编码 → 字符串constencodedawaitBase64Util.encodeToStr(raw);constdecodedRawawaitBase64Util.decode(encoded);constdecodedthis.uint8ArrayToText(decodedRaw);this.results[{label:encodeToStr (Promise),value:encoded,byteLen:raw.length},{label:decode (Promise)→Str,value:decoded,byteLen:decoded.length},];this.addLog(Async,encodeToStr decode 完成,success);}else{// 组合四异步编码 → Uint8ArrayconstencodedawaitBase64Util.encode(raw);constdecodedawaitBase64Util.decode(encoded);this.results[{label:encode (Promise),value:this.uint8ArrayToText(encoded),byteLen:raw.length},{label:decode (Promise),value:this.uint8ArrayToText(decoded),byteLen:decoded.length},];this.addLog(Async,encode decode 完成,success);}}}解码演示独立 TabasyncrunDecode(){if(this.inputText.trim()){this.addLog(解码,请输入 Base64 字符串,warn);return;}try{letdecoded:Uint8Array;if(this.syncMode){decodedBase64Util.decodeSync(this.inputText.trim());}else{decodedawaitBase64Util.decode(this.inputText.trim());}consttextthis.uint8ArrayToText(decoded);this.results[{label:解码结果,value:text,byteLen:decoded.length},];this.addLog(解码,解码成功${decoded.length}字节,success);}catch(e){this.addLog(解码,解码失败:${(easError).message},error);}}四、选型矩阵场景数据量推荐方法原因编码小图标/小图片 1KBencodeToStrSync同步简洁数据量小不卡编码大图片/文件 100KBencodeToStr(async)大数据异步不阻塞 UI解码服务器 Token几十字节decodeSync同步即可超小数据解码大文件 100KBdecode(async)异步解码避免卡顿需要继续传给其他方法任意看下游是否异步链路保持链路一致性在aboutToAppear中初始化任意Sync版本生命周期不是 async五、关于 util.Type 参数所有方法都有一个可选的options?: util.Type参数用于指定 Base64 编码的变体值说明util.Type.BASIC标准 Base64默认使用和/末尾补util.Type.MIMEMIME 格式每 76 字符加一个换行\r\nutil.Type.URL_SAFEURL 安全格式用-替代_替代/util.Type.BASIC_URL_SAFEURL 安全但不补大多数场景用默认值不传 options即可。如果编码结果要放进 URL 参数里应该用util.Type.URL_SAFE否则和/在 URL 中有特殊含义会出问题。六、常见踩坑踩坑1同步方法在大文件上卡 UI// ❌ 大文件用同步会冻结界面constbigFile:Uint8Array...// 5MB 图片constencodedBase64Util.encodeToStrSync(bigFile);// 卡住 UI// ✅ 改用异步constencodedawaitBase64Util.encodeToStr(bigFile);// 不阻塞踩坑2解码失败没有 try-catch// ❌ 没有处理解码失败constdecodedBase64Util.decodeSync(invalidBase64String);// 可能抛出// ✅ 包一层 try-catchtry{constdecodedBase64Util.decodeSync(invalidBase64String);}catch(e){console.error(解码失败:,(easError).message);}Base64 字符串如果不合法含有非法字符、长度不对decodeSync会抛异常。踩坑3混用编码类型// ❌ 用 URL_SAFE 编码却用默认选项解码constencodedBase64Util.encodeToStrSync(data,util.Type.URL_SAFE);constdecodedBase64Util.decodeSync(encoded);// 可能出错// ✅ 编解码选项要一致constdecodedBase64Util.decodeSync(encoded,util.Type.URL_SAFE);七、总结选型口诀数据小 10KB→ 用 Sync数据大 100KB→ 用 async/await不确定 → 用 async安全边际更大要放 URL 里 → 加util.Type.URL_SAFE解码一定要 try-catch