二十一、【鸿蒙 NEXT】分词和汉字转拼音

【前言】

在某些功能场景,比如实现一个本地搜索功能时,可能需要支持中文搜索,同时支持拼音搜索。这里就会涉及到两个功能点,一个是中文转拼音,一个是将中文进行分词。同时这里有个注意点如果调用系统接口进行批量分词时,使用不当会导致UI卡顿。下面介绍下在鸿蒙next系统中,怎么实现这两个功能,以及怎么避免UI卡顿

1、中文转拼音

在系统接口中有个i18n的工具类,该工具类提供了一个Transliterator工具类,可以实现中文转拼音能力,代码如下

其中res1是包含声调的,res2是不包含声调的

javascript 复制代码
let res1:string = i18n.Transliterator.getInstance('Han-Latin').transform('中国')
let res2:string = i18n.Transliterator.getInstance('Latin-ASCII').transform(res1)

2、分词

在做功能搜索功能时,会将功能名称分词出不同的词语,来适配用户的搜索。这里系统提供了一个 分词功能,textProcessing是系统分词的一个工具类,代码如下,代码将"词语搜索"四个字分词层"词语"和"搜索"两个词

javascript 复制代码
 textProcessing.getWordSegment('词语搜索').then(wordSegments => {
     let words = wordSegments.map(wordSegment => wordSegment.word)
     console.log(`词语搜索 => ${JSON.stringify(words)}`)
   })

3、分词的注意点

这里要注意一点,如果使用不当,可能会造成UI界面的卡顿。

在调用系统分词接口时,实际是跨进程调用系统能力。如果我们一次性循环调用很多次分词接口,由于系统的分词进程最大开两个线程处理分词。因此我们如果循环大量调用接口,会导致我们app一直处于等待状态,而且会影响UI的正常展示。这种阻塞即使我们在app中启动子线程去调用系统接口,也没法起到效果。因为实际上我们跨进程调用分词接口时,本身会启动一个子线程去调用,真正造成UI卡顿的原因是,我们循环大批量开启跨进程调用,会导致app的线程资源耗尽,导致我们app其他线程无法正常获取线程资源。比如会影响网络请求,我们很多UI的展示依赖网络请求的返回值,由于线程资源耗尽,网络请求只能等待。从而影响UI正常展示。

解决方法就是我们可以分批次调用系统接口,比如每批次调用4次,等到前面的处理完成后,再继续下一批次调用。完整的代码实现如下,这里首先在app子线程去做分词功能,并在子线程中分批次调用。我们最终在app启动时调用SegmentUtil.segment();方法实现批量分词效果

javascript 复制代码
// 分词工具类,开启子线程执行
import { textProcessing } from "@kit.NaturalLanguageKit"
import { PromiseBatchUtils } from "./PromiseBatchUtils"
import { taskpool } from "@kit.ArkTS"

export class SegmentUtil {
  public static async segment() {
    let segmentResult = await taskpool.execute(segments) as Promise<string[][]>
    console.log(`segmentResult is ${JSON.stringify(segmentResult)}`)
  }
}

@Concurrent
async function segments():Promise<string[][]> {
  let arr:string[] = ['词语搜索','词语搜索','词语搜索','词语搜索','词语搜索','词语搜索','词语搜索','词语搜索','词语搜索','词语搜索','词语搜索','词语搜索']
  let arrPromise:(()=>Promise<string[]>)[] = arr.map(str => async () => {
    let wordSegments = await textProcessing.getWordSegment('词语搜索')
    return wordSegments.map(wordSegment => wordSegment.word)
  })
  let result = await PromiseBatchUtils.runWithBatch(arrPromise, 4)
  return result
}

// 分批次调用系统分词

export class PromiseBatchUtils {
  public static async runWithBatch<T>(tasks:(() => Promise<T>)[], batchNum:number):Promise<T[]> {
    let results:T[] = []
    let execute:Promise<void>[] = []
    let index = 0
    while (index < tasks.length) {
      if (execute.length < batchNum) {
        let taskIndex = index++
        console.log(`start index ${taskIndex}`)
        let executePromise = tasks[taskIndex]()
          .then(result => {
            results[taskIndex] = result
            console.log(`end index ${taskIndex}`)
          }).finally(() => {
            let executeIndex = execute.indexOf(executePromise)
            if (executeIndex > -1) {
              execute.splice(executeIndex,1)
            }
          })
        execute.push(executePromise)
      } else {
        await Promise.race(execute)
      }
    }
    await Promise.all(execute)
    return results
  }
}
相关推荐
小镇敲码人14 小时前
探索华为CANN框架中的Ops-NN仓库
华为·cann·ops-nn
lbb 小魔仙15 小时前
【HarmonyOS实战】OpenHarmony + RN:自定义 useValidator 表单验证
华为·harmonyos
仓颉编程语言17 小时前
鸿蒙仓颉编程语言挑战赛二等奖作品:TaskGenie 打造基于仓颉语言的智能办公“任务中枢”
华为·鸿蒙·仓颉编程语言
一起养小猫17 小时前
Flutter for OpenHarmony 实战:扫雷游戏完整开发指南
flutter·harmonyos
小哥Mark19 小时前
Flutter开发鸿蒙年味 + 实用实战应用|绿色烟花:电子烟花 + 手持烟花
flutter·华为·harmonyos
小镇敲码人19 小时前
剖析CANN框架中Samples仓库:从示例到实战的AI开发指南
c++·人工智能·python·华为·acl·cann
前端不太难20 小时前
HarmonyOS 游戏里,Ability 是如何被重建的
游戏·状态模式·harmonyos
lbb 小魔仙20 小时前
【HarmonyOS实战】React Native 鸿蒙版实战:Calendar 日历组件完全指南
react native·react.js·harmonyos
一只大侠的侠21 小时前
Flutter开源鸿蒙跨平台训练营 Day 3
flutter·开源·harmonyos
盐焗西兰花21 小时前
鸿蒙学习实战之路-Reader Kit自定义字体最佳实践
学习·华为·harmonyos