鸿蒙极速入门(六)-加载请求状态管理-LoadState+观察者模式

背景

1、在ArkTS的架构中,没有明确的可管理的加载请求状态的脚手架,在进行网络请求过程中,无法简单的进行交互响应。

2、参考Android中的LoadState写了一个简单的脚手架,以便在日常开发过程中,管理加载请求状态和UI交互。

脚手架说明与源码

1、状态机LoadState

使用一个状态机,分别对应网络请求过程中的Loading(发起请求)、Loaded(请求成功)、LoadError(请求失败)状态,并支持链式调用:

ts 复制代码
/**
 * 网络请求MVVM数据模型,由子类实现状态机管理,由方法实现回调监听
 */
export abstract class LoadState {
  /**
   * loading函数,如果当前状态是Loading,则调用回调函数
   * @param callBack 回调函数
   * @returns this
   */
  loading(callBack?: () => void): this {
    if (this instanceof Loading) {
      callBack?.call(null);
    }
    return this;
  }

  /**
   * loaded函数,如果当前状态是Loaded,则调用回调函数
   * @param callBack 回调函数
   * @returns this
   */
  loaded(callBack?: (result: Loaded<any>) => void): this {
    if (this instanceof Loaded) {
      callBack?.call(null, this);
    }
    return this;
  }

  /**
   * loadError函数,如果当前状态是LoadError,则调用回调函数
   * @param callBack 回调函数
   * @returns this
   */
  loadError(callBack?: (error: LoadError) => void): this {
    if (this instanceof LoadError) {
      callBack?.call(null, this);
    }
    return this;
  }
}

/**
 * Loading类,继承自LoadState类
 */
export class Loading extends LoadState {}

/**
 * Loaded类,继承自LoadState类,包含一个result属性和一个data方法
 */
export class Loaded<T> extends LoadState {
  result?: T;

  constructor(data: T) {
    super();
    this.result = data;
  }

  data(): T | undefined {
    return this.result;
  }
}

/**
 * LoadError类,继承自LoadState类,包含code和message属性
 */
export class LoadError extends LoadState {
  code?: number;
  message?: string;

  constructor(code: number, message: string) {
    super();
    this.code = code;
    this.message = message;
  }
}

2、观察者模式

ArtTS没有提供开箱即用的观察者模式框架,也无法直接使用RxJS框架,所以自己手写一个简单的ValueNotifier作为观察者实现类:

ts 复制代码
/**
 * ValueNotifier类,包含_value、listeners属性和addListener、notifyListeners、value方法
 */
export class ValueNotifier<T> {
  private _value: T;
  listeners: Array<() => void> = [];

  constructor(value: T) {
    this._value = value;
  }

  get value(): T {
    return this._value;
  }

  set value(value: T) {
    this._value = value;
    this.notifyListeners();
  }

  addListener(listener: () => void) {
    this.listeners.push(listener);
  }

  notifyListeners() {
    for (let listener of this.listeners) {
      listener();
    }
  }
}

使用示例

以获取一个车辆详情的场景来模拟网络请求和数据处理

1、ViewModel

ts 复制代码
import { Loaded, LoadError, Loading, LoadState, ValueNotifier } from './LoadState';

export class VehicleViewModel {
  lsVehicleDetail: ValueNotifier<LoadState | null>;

  constructor() {
    this.lsVehicleDetail = new ValueNotifier<LoadState | null>(null);
  }

  // 获取车辆详情
  async getVehicleDetail() {
    // 发起请求
    this.lsVehicleDetail.value = new Loading();

    await new Promise(resolve => setTimeout(resolve, 3000));

    // 获得数据
    this.lsVehicleDetail.value = new Loaded("aa");

    await new Promise(resolve => setTimeout(resolve, 3000));

    // 模拟网络报错
    this.lsVehicleDetail.value = new LoadError(123, "error");
  }
}

2、页面处理

ts 复制代码
@Component
export struct VehicleComponent {
  private vm: VehicleViewModel = new VehicleViewModel();

  aboutToAppear() {

    this.vm.lsVehicleDetail.addListener(() => {
      this.vm.lsVehicleDetail.value?.loading(() => {
        // 开始网络请求
        console.log(`hello1:start Loading`);
      }).loaded((result) => {
        let data = result?.data() as String
        console.log(`hello2:${result} - ${data}`);
      }).loadError((error) => {
        console.log(`hello3:${error?.code} - ${error?.message}`);
      });
    });
  }
}

3、日志打印结果

log 复制代码
hello1:start Loading
hello2:[object Object] - aa
hello3:123 - error
相关推荐
Kevin Coding9 小时前
JsonConvert:适用于 Android、鸿蒙与 Flutter 的 JSON 转 Model 插件
android·flutter·harmonyos
m0_7496902311 小时前
【寻迹校园 HarmonyOS NEXT 实战 28】不交换手机号也能交接:固定校内交接点的隐私设计
华为·harmonyos·arkts·产品设计·隐私设计·安全交接
Magic-ZYJ11 小时前
HarmonyOS Stage 模型实战:UIAbility 生命周期如何驱动页面安全状态
安全·华为·harmonyos·鸿蒙·移动端开发·独立开发者·心晴手记
贾伟康11 小时前
【中国方言题库|09】HarmonyOS ArkTS 方言搜索实战:实现词语检索和无结果反馈
harmonyos·arkts·状态管理·arkui·本地搜索
Dovis(誓平步青云)12 小时前
从手机单栏到平板分栏:任务清单的筛选、选中态与不可变更新
华为·harmonyos
梦想不只是梦与想12 小时前
鸿蒙 AppGallery Connect:查看应用信息(三)
harmonyos·appgallery·client id·app id·developer id
贾伟康12 小时前
【中国方言题库|03】HarmonyOS ArkTS 四川话分库实战:复用题库组件并保持地区参数清晰
harmonyos·arkts·arkui·路由传参·组件复用
贾伟康13 小时前
【中国方言题库|10】HarmonyOS ArkTS 语音播放实战:管理读音播放与页面生命周期
生命周期·harmonyos·arkts·语音合成·texttospeech
YM52e1 天前
鸿蒙ArkTS实战项目 - 门店陈列巡检台:巡检卡片与多列切换实现
学习·华为·harmonyos
lilian2331 天前
Harmony os 技术实战|拼豆制图27:用单字符编码承载 50 张 70×70 图纸
前端·数据库·华为·harmonyos