背景

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. C++图像处理函数及程序(一)

    C++开源项目: Boost.GIL:通用图像库 CImg :用于图像处理的小型开源C++工具包 CxImage :用于加载,保存,显示和转换的图像处理和转换库,可以处理的图片格式包括 BMP, JP ...

  2. 记一次因为C#官方扩展导致自动补全出错的情况 (C# & Godot)

    现象 最近使用Vscode结合Godot使用时突然发现自动补全出问题了,发现一部分自动补全能弹出补全项目,但是确认后不起作用,还会吞掉弹出自动补全后输入的字符.大概是下图这样的感觉(截图时已修好,图为 ...

  3. Maven资源导出问题所需配置

    <!--在build中配置resources,来防止我们资源导出失败的问题--> <build> <resources> <resource> < ...

  4. 【go笔记】使用sqlx操作MySQL

    前言 go在操作MySQL时,可以使用ORM(比如gorm.xorm),也可以使用原生sql.本文以使用sqlx为例,简单记录步骤. go version: 1.16 安装相关库 # mysql驱动 ...

  5. Vue3 路由优化,使页面初次渲染效率翻倍

    3996 条路由? addRoute函数用了大约1s才执行完毕.通过观察,发现居然有3996条路由记录. 可是项目并没有这么多的页面啊~ 重复路由 let routes: Array<Route ...

  6. 解决linux系统的kdump服务无法启动的问题

    **问题:项目麒麟系统服务器的kdump服务无法启动,没有相关日志无法定位问题.** 1.查看服务状态是关闭的,重启系统也无法启动 systemctl status kdump 2.修改grub参数 ...

  7. lea指令调用

    lea指令(Load Effective Address)在x86汇编语言中的作用是将一个有效地址(即一个内存地址或寄存器地址的偏移量)加载到目标寄存器中,而不是加载一个实际的内存值. lea指令的使 ...

  8. 使用C#创建安装Windows服务程序(最全教程)

    开发语言:C# 开发环境: Visual Studio 2022 微软官方文档:https://learn.microsoft.com/zh-cn/dotnet/framework/windows-s ...

  9. 数据api接口就是应用集成吗?

    ​ 数据 API 接口和应用集成是两个不同的概念,但是它们之间有一定的联系.数据 API 接口是一种用于访问和传输数据的标准化接口,而应用集成则是将不同的应用程序和系统整合在一起,实现数据和业务流程的 ...

  10. ShardingSphere实战

    前言 本文主要从sharding最新版本5.1.2版本入手搭建,按主键ID和时间进行分表. 本文主要介绍搭建过程,有兴趣了解shardingsphere的同学可以先自行查阅相关资料. shardsph ...