实现效果
1.分析
- 请求 接口 获取-一级商品分类 获取一级分类id
- 遍历一级分类id,使用http 生成一组请求Promise,去请求 接口二级分类数据
- 使用Promise.allSettled来一次性发送第二步生成的Promise数组得到所有数据
- 渲染到页面
基础模板
interface CategoryData {
id: string
name: string
picture: string
children?: CategoryData[]
}
@Entry
@Component
struct mainContent {
@State topCategoryList: CategoryData[] = [
{
"id": "1005000",
"name": "居家",
"picture": "http://yjy-xiaotuxian-dev.oss-cn-beijing.aliyuncs.com/picture/2021-05-06/201516e3-25d0-48f5-bcee-7f0cafb14176.png",
"children": [
{
"id": "1005009",
"name": "茶咖酒具",
"picture": "https://yanxuan.nosdn.127.net/3102b963e7a3c74b9d2ae90e4380da65.png?quality=95&imageView"
},
{
"id": "1007000",
"name": "水具杯壶",
"picture": "https://yanxuan.nosdn.127.net/45b50d5f8afbd6fdef97314647dcb7db.png?quality=95&imageView"
},
{
"id": "1017000",
"name": "宠物食品",
"picture": "https://yanxuan.nosdn.127.net/b42a85ef15f856081ea9f49e5f6893e2.png?quality=95&imageView"
},
{
"id": "109248004",
"name": "宠物用品",
"picture": "https://yanxuan.nosdn.127.net/e766b09029ca00680d1e651b5cdc42bd.png?quality=95&imageView"
}
]
}
]
build() {
List() {
ForEach(this.topCategoryList, (item: CategoryData) => {
ListItemGroup({ header: this.groupHeader(item.name, item.picture) }) {
ForEach(item.children, (it: CategoryData) => {
ListItem() {
Column() {
Image(it.picture)// .width('80%')
.height(90)
Text(it.name)
.fontSize(15)
}
.width('100%')
.alignItems(HorizontalAlign.Center)
}
})
}
})
}
.backgroundColor(Color.White)
.lanes(4)
.divider({ strokeWidth: 10, color: '#f6f6f6' })
.scrollBar(BarState.Off)
}
@Builder
groupHeader(title: string, icon: string) {
Row({ space: 5 }) {
Text(title)
.fontWeight(FontWeight.Bold)
Image(icon)
.width(20)
}
.width('100%')
.padding(10)
.backgroundColor(Color.White)
}
}
具体实现步骤
1.获取一级分类数据:
发起HTTP请求获取一级分类数据。
将响应结果转换为iTop1Data类型对象。
2.提取一级分类ID:
从一级分类数据中提取所有分类的ID,存储在topids数组中。
3.发起多个二级分类数据请求:
遍历topids数组,对每个ID发起新的HTTP请求以获取对应的二级分类数据。
将每个请求的结果存储在一个Promise<http.HttpResponse>类型的数组plist中。
4.等待所有请求完成:
使用Promise.allSettled等待所有二级分类数据请求完成。
处理每个请求的结果:
如果请求成功,则解析响应结果为iTop2Data类型对象。
将解析后的二级分类数据追加到this.topCategoryList数组中。
如果请求失败,则忽略该结果,将其视为空字符串。
核心代码
/**
* 异步获取顶级分类列表
* 此函数通过异步请求获取一级分类数据,并根据一级分类id获取对应的二级分类数据
*/
async getTopCategoryList() {
// 请求一级分类数据
const top1 = await req.request(`https://hmajax.itheima.net/api/category/top`)
// 将请求结果转换为对象
let obj: iTop1Data = JSON.parse(top1.result.toString())
// 获取一级分类id
let topids: string[] = obj.data.map(item => {
return item.id
})
// 创建一个promise数组
let plist: Promise<http.HttpResponse>[] = []
// 遍历topids,发起二级分类数据请求
topids.forEach(id => {
let reqParam = req.request(`https://hmajax.itheima.net/api/category/sub?id=${id}`)
plist.push(reqParam) // 将请求结果push到plist中
})
// 等待所有请求完成
Promise.allSettled(plist)
.then(res => {
// 遍历plist,处理请求结果
let top2list = res.map(pres => {
if (pres.status == 'fulfilled') { // 判断请求是否成功
return pres.value.result
} else {
return ''
}
})
// 将请求结果转换为对象,并将数据添加到topCategoryList中
top2list.map(item => {
let obj: iTop2Data = JSON.parse(item.toString())
this.topCategoryList.push(obj.data)
})
})
}
完整代码
import { http } from '@kit.NetworkKit'
const req = http.createHttp()
export interface iTop1Data {
data: CategoryData[];
message: string
}
export interface iTop2Data {
data: CategoryData;
message: string
}
interface CategoryData {
id: string
name: string
picture: string
children?: CategoryData[]
}
@Entry
@Component
struct mainContent {
@State topCategoryList: CategoryData[] = []
aboutToAppear(): void {
this.getTopCategoryList()
}
async getTopCategoryList() {
const top1 = await req.request(`https://hmajax.itheima.net/api/category/top`) // 请求一级分类数据
let obj: iTop1Data = JSON.parse(top1.result.toString()) // 将请求结果转换为对象
let topids: string[] = obj.data.map(item => { // 获取一级分类id
return item.id
})
let plist: Promise<http.HttpResponse>[] = [] // 创建一个promise数组
topids.forEach(id => { // 遍历topids
let reqParam = req.request(`https://hmajax.itheima.net/api/category/sub?id=${id}`)
plist.push(reqParam) // 将请求结果push到plist中
})
Promise.allSettled(plist)// 等待所有请求完成
.then(res => {
let top2list = res.map(pres => { // 遍历plist
if (pres.status == 'fulfilled') { // 判断请求是否成功
return pres.value.result
} else {
return ''
}
})
top2list.map(item => {
let obj: iTop2Data = JSON.parse(item.toString()) // 将请求结果转换为对象
this.topCategoryList.push(obj.data) // 将请求结果添加到topCategoryList中
})
})
}
build() {
List() {
ForEach(this.topCategoryList, (item: CategoryData) => {
ListItemGroup({ header: this.groupHeader(item.name, item.picture) }) {
ForEach(item.children, (it: CategoryData) => {
ListItem() {
Column() {
Image(it.picture)// .width('80%')
.height(90)
Text(it.name)
.fontSize(15)
}
.width('100%')
.alignItems(HorizontalAlign.Center)
}
})
}
})
}
.backgroundColor(Color.White)
.lanes(4)
.divider({ strokeWidth: 10, color: '#f6f6f6' })
.scrollBar(BarState.Off)
}
@Builder
groupHeader(title: string, icon: string) {
Row({ space: 5 }) {
Text(title)
.fontWeight(FontWeight.Bold)
Image(icon)
.width(20)
}
.width('100%')
.padding(10)
.backgroundColor(Color.White)
}
}