鸿蒙极速入门(六)-加载请求状态管理-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
相关推荐
干词10 分钟前
干词入选华为应用首页“精选推荐”鸿蒙/安卓/双端支持!
华为·harmonyos·雅思·背单词·四六级·干词·精选推荐
xmdy586625 分钟前
Flutter + 开源鸿蒙实战|城市智慧停车管理系统 Day1 项目初始化+架构搭建+全局依赖集成+多端适配基座
flutter·开源·harmonyos
轻口味1 小时前
HarmonyOS 6.1 全栈实战录 - 06 状态定力:PersistenceV2 深度进阶与集合类型持久化实战
华为·harmonyos
key_3_feng2 小时前
鸿蒙音乐播放器应用开发指南
华为·harmonyos
大雷神2 小时前
HarmonyOS APP<<古今职鉴定>>开源教程第2篇:开发环境搭建:DevEco Studio 全攻略
华为·华为云·harmonyos
Swift社区2 小时前
鸿蒙 PC 多窗口系统:一次讲透实现原理
华为·harmonyos
xmdy58662 小时前
Flutter + 开源鸿蒙实战|城市智慧停车管理系统 Day3 车场详情+车位预约+计时计费算法+路线导航+常用车场缓存持久化
flutter·开源·harmonyos
xmdy58662 小时前
Flutter+开源鸿蒙实战|城市共享驿站智能存取系统 Day6 全局UI精细化美化+通用组件封装+反馈设置模块+隐私弹窗+鸿蒙打包签名适配+项目整体重构
flutter·开源·harmonyos
三声三视2 小时前
Electron+鸿蒙桌面应用实战:跨平台开发完全指南
electron·harmonyos·鸿蒙·桌面
求学中--2 小时前
鸿蒙实战:用状态管理实现一个完整的Todo应用,从@State到@Provide全链路打通
华为·harmonyos·组件化开发·完整项目