首先请求列表数据,然后判断列表中数据的状态,看是否有需要轮询的项,有的话就轮询。组件销毁前结束轮询来清空定时器,防止内存泄漏。
enum Status {
ING, // 进行中
FAILED, // 失败
SUCCESS // 成功
}
const list = ref<...[]>([])
// 取列表数据
function getList () {
// API为封装的接口集合
API.getList({ ... })
.then(res => {
list.value = res || []
handleList()
})
}
getList()
// 根据数据项的状态分类处理列表数据
function handleList() {
// 状态为进行中的数据项
let ings = list.value?
// 取出列表中进行中状态的数据
.filter(n => n.status === Status.ING)?
// 取对应数据的id
.map(m => m.id)
if (ings?.length) {
// 有进行中的数据,需轮询
poll(ings)
} else {
// 没有进行中的数据,结束轮询
endPoll()
}
}
let statusTimer: NodeJS.Timeout
// 轮询
function poll(ings: string[]) {
endPoll()
timer = setTimeout(() => getDetails(ings), 6e4)
}
// 根据id再获取详情
async function getDetails(ings: string[]) {
// 遍历状态为进行中的数据项的数组,分别调用详情接口
const promises = ings?.map(n => getInfo(n))
const vals = await Promise.all(promises)
if (vals?.length) {
vals?.forEach((value) => doDetail(value))
}
handleList()
}
// 请求详情接口
function getInfo(id: string) {
return API.getInfo({ id })
}
// 处理详情
function doDetail(data: Item) {
const cur = list.value?.find(n => n.id === data?.id)
if (cur) {
cur.status = data.status
}
}
// 结束轮询
function endPoll() {
clearTimeout(timer)
}
// 组件销毁前结束轮询
onUnmounted(() => endPoll())