Vue项目中根据返回的数据状态轮询接口

129 阅读1分钟

首先请求列表数据,然后判断列表中数据的状态,看是否有需要轮询的项,有的话就轮询。组件销毁前结束轮询来清空定时器,防止内存泄漏。

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())