背景

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. SpringBoot项目:net.sf.jsqlparser.parser.ParseException: Encountered unexpected token:XXXXX

    原文地址 写在前面 最近开发过程中,在where条件中使用IF函数,在MySQL数据库中,使用Navicat运行没有问题,但是运行项目的时候,死活过不去,一直报错,后来一番折腾找到了解决方案,所以,以 ...

  2. shell 并发

    #!/bin/bash # 设置并发数 thread_num=3 # 创建管道文件 FIFO=/tmp/$$-FIFO mkfifo $FIFO # 使用句柄打开管道文件 exec 1000<& ...

  3. 深度系统安装wine

    step1: 输入命令: sudo dpkg --add-architecture i386 step2: 1.切换成管理员权限: sudo su 2.打开源文件 vi /etc/apt/source ...

  4. Topic太多,RocketMQ炸了!

    网上博客常说,kafka的topic数量过多会影响kafka,而RocketMQ不会受到topic数量影响. 但是,果真如此吗? 最近排查一个问题,发现RocketMQ稳定性同样受到topic数量影响 ...

  5. 小白也能搞定!Windows10上CUDA9.0+CUDNN7.0.5的完美安装教程

    前言: 为什么要在本地电脑安装 CUDA,CUDA 是什么的,用来做什么?我想,点击标题进来的小伙伴,应该都清楚这些.不管你是用来做什么,或者跟我一样为了跑 Tensorflow 的 Object D ...

  6. 因为此网站发送了 Google Chrome 无法处理的杂乱凭据

    原文地址 thisisunsafe this is unsafe 这是不安全的,呵呵~ 具体描述 在chrome该页面上,直接键盘敲入这11个字符:thisisunsafe (鼠标点击当前页面任意位置 ...

  7. Mybatis开发中的常用Maven配置

    Mybatis导入Maven配置 <!-- MyBatis导入 --> <dependency> <groupId>org.mybatis</groupId& ...

  8. 免费拥有自己的 Github 资源加速器

    TurboHub 是一个免费的 Github 资源加速下载站点,可以帮助你快速下载 Github 上的资源.其核心逻辑是通过 Azure Static Web Apps 服务和 Azure Funct ...

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

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

  10. Python Web:Django、Flask和FastAPI框架对比

    Django.Flask和FastAPI是Python Web框架中的三个主要代表.这些框架都有着各自的优点和缺点,适合不同类型和规模的应用程序. Django: Django是一个全功能的Web框架 ...