背景

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

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

脚手架说明与源码

1、状态机LoadState

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

/**
* 网络请求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作为观察者实现类:

/**
* 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

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、页面处理

@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、日志打印结果

hello1:start Loading
hello2:[object Object] - aa
hello3:123 - error

鸿蒙极速入门(六)-加载请求状态管理-LoadState+观察者模式的更多相关文章

  1. Unity动态加载和内存管理(三合一)

    原址:http://game.ceeger.com/forum/read.php?tid=4394#info 最近一直在和这些内容纠缠,把心得和大家共享一下: Unity里有两种动态加载机制:一是Re ...

  2. [转]全面理解Unity加载和内存管理

    [转]全面理解Unity加载和内存管理 最近一直在和这些内容纠缠,把心得和大家共享一下: Unity里有两种动态加载机制:一是Resources.Load,一是通过AssetBundle,其实两者本质 ...

  3. 全面理解Unity加载和内存管理

     全面理解Unity加载和内存管理http://game.ceeger.com/forum/read.php?tid=4394&fid=2&uid=6507 1.用简单的“for”循环 ...

  4. lmsw - 加载机器状态字

    将源操作数加载到机器状态字,即寄存器 CR0 的位 0 到 15.源操作数可以是 16 位通用寄存器或内存位置.只有源操作数的低 4 位(也就是 PE.MP.EM 及 TS 标志)会加载到 CR0.C ...

  5. php+ajax实现拖动滚动条分批加载请求加载数据

    HTML: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w ...

  6. FusionCharts简单教程(六)------加载外部Logo

    一.加载外部文件Logo       在使用FusionCharts时,我们可能需要在加载图像的时候需要在图表中显示标识.图片等等.这里我们可以使用logoURL属性来实现.如: <chart ...

  7. Unity3D 游戏开发构架篇 —— 动态大场景生成 = 区域加载+对象池管理

    项目做一个类似无尽模式的场景,想了一想,其实方法很简单,做一个相关的总结. 主要先谈一谈构架,后期附上代码. 一.区域加载 其实无尽场景的实现很简单,因为屏幕限制,那么不论何时何地,我们只能看到自己的 ...

  8. Unity 全面理解加载和内存管理

    最近一直在和这些内容纠缠,把心得和大家共享一下: Unity里有两种动态加载机制:一是Resources.Load,一是通过AssetBundle,其实两者本质上我理解没有什么区别.Resources ...

  9. 理解Unity加载和内存管理

    转自:http://game.ceeger.com/forum/read.php?tid=4394#info Unity里有两种动态加载机制:一是Resources.Load,一是通过AssetBun ...

  10. vue从入门到进阶:Vuex状态管理(十)

    Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化. 在 Vue 之后引入 vuex 会进行自动 ...

随机推荐

  1. EaselJS 源码分析系列--第一篇

    什么是 EaselJS ? 事儿还得从 Flash 说起,因为我最早接触的就是 Flash, 从 Flash 入行编程的 Flash 最早的脚本是 Actionscript2.0 它的 1.0 我是没 ...

  2. 快速打开指定目录的cmd

    待解决问题 在使用dirsearch.sqlmap等工具时需要进入对应的目录再打开cmd,现要实现配合utools快速打开对应目录的cmd 解决办法:创捷快捷方式 在对应的文件夹下创建一个快捷方式,对 ...

  3. 初始elasticSearch

    elasticSearch 大致印象 为什么用? mysql更擅长于crud等操作,当一张表达到百万级别时,检索速度过慢 es检索速度快 基本概念 Index索引(两层意思) 动词:类似mysql的i ...

  4. AMH安装Nextcloud出现Access denied

    AMH部署了LAMP或者LNMP,然后常规安装Nextcloud,安装完成后跳转到首页就出现Access denied.Nextcloud的文件夹权限已经修改,可读写.http://127.0.0.1 ...

  5. 简单的python3脚本:从日志中提取信息

    命名:log_extractor.py or download_stats_extractor.py # coding:utf-8 #!/usr/bin/python3 def filter_line ...

  6. 与AI对话 -- 20230221 -- linux 性能分析相关的软件包

    linux 性能分析相关的软件包有哪些,各自包含了哪些命令 sysstat:sysstat 包含了丰富的监控系统性能的工具,例如 sar(系统性能分析器).iostat(设备 IO 状态分析器).mp ...

  7. ubuntu安装rpm格式包

    首先,我们要安装alien这一软件: $sudo apt-get install alien ##alien默认没有安装,所以首先要安装它 $sudo alien xxxx.rpm ##将rpm转换为 ...

  8. AcWing 4798. 打怪兽题解

    可以从 \(1\) 枚举到 \(n\) 表示要打多少个怪兽. 因为你要打 \(t\) 个怪兽,并不管顺序,所以我们可以对 \([1, t]\) 这一段进行排序,然后计算 \(a[t], a[t - 2 ...

  9. SNAT与DNAT原理及应用

    SNAT与DNAT原理及应用 当内部地址要访问公网上的服务时(如httpd访问),内部地址会主动发起连接,由路由器或者防火墙上的网关对内部地址做个地址转换,将内部地址的私有IP转换为公网的公有IP,网 ...

  10. 浅谈Mysql读写分离的坑以及应对的方案

    一.主从架构 为什么我们要进行读写分离?个人觉得还是业务发展到一定的规模,驱动技术架构的改革,读写分离可以减轻单台服务器的压力,将读请求和写请求分流到不同的服务器,分摊单台服务的负载,提高可用性,提高 ...