背景

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. 即构 SDK 6月迭代:新增拉流画面镜像等功能,为开发者提供更大便利

    即构SDK6月新版本已上线,本月SDK迭代主要新增了拉流画面镜像功能,媒体播放器新增支持缓存相关的设置,新增支持设置对焦模式和曝光模式等功能,多个功能模块的灵活设置,让开发者能更便利的自定义选择,为用 ...

  2. MD文本编辑工具推荐-matktext

    最开始是用vscode编辑markdown文档,左边写右边看效果的实时渲染模式,对于markdown编辑来说是多余的,多是文字类的内容,配以插图,复杂表格和脑图则更少.之后接触到Typora,所打即所 ...

  3. BUUCTF-MISC-面具下的flag(vmdk的解压和Brainfuck与Ook解密)

    准备工作 下载附件得到一个一张图片 丢入winhex,发现还有一个flag.vmdk文件 vmdk文件其实是虚拟机使用的硬盘文件 打开kali binwalk -e mianju.jpg 关键步骤 这 ...

  4. Django: django.core.exceptions.ImproperlyConfigured: Could not resolve URL for hyperlinked relationship using view name "game-detail".

    错误原因:在序列化时,使用了参数`url`,但在`urls.py`文件中,没有使用命名 # urls.py from django.urls import path from RESTSerializ ...

  5. 好用的css3特性-动画和3d变换

    上一篇文章总结了过渡和2D变化,这一篇来总结一下动画和3D变换,动画可用的场景也很多,比如在加载的页面的时候,可以放置一个gif图,也可以自定义小动画来缓解用户等待的焦虑感,比如以下三个小圆圈转圈圈的 ...

  6. Nginx反向代理服务流式输出设置

    Nginx反向代理服务流式输出设置 1.问题场景 提问:为什么我部署的服务没有流式响应 最近在重构原有的GPT项目时,遇到gpt回答速度很慢的现象.在使用流式输出的接口时,接口响应速度居然还是达到了3 ...

  7. centos7.X安装nginx – 东凭渭水流

    1.安装nginx需要使用root用户 2.配置nginx源 rpm -ivh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release ...

  8. fastapi启动后访问docs不显示页面的问题

    笔者之前正常使用fastapi的docs接口进行各种接口调试,使用很正常,之前安装也都是正常安装流程,没有做任何修改,可以突然有一天不知道为啥,docs接口打开是空白的,接口也没有报错,就是空白,摸索 ...

  9. 重复的dna序列

    DNA序列 由一系列核苷酸组成,缩写为 'A', 'C', 'G' 和 'T'.. 例如,"ACGAATTCCG" 是一个 DNA序列 . 在研究 DNA 时,识别 DNA 中的重 ...

  10. windows无法连接VMware虚拟机的linux

    遇到的问题:今天使用xshell连接虚拟机,无法连接. 解决过程: 1.测试ping, linux虚拟机能ping通windows主机,可是windows主机ping不通linux虚拟机. 2.查看v ...