SOURCE

console 命令行工具 X clear

                    
>
console
//请求(任务)失序问题 的处理
// 1 第一个未完成 则后续直接无视
// 2 前一个未完成时再次触发则取消前一个的任务处理
// 3 将所有任务的成功函数 加入稀松数组中,每个成功函数中都根据指针执行数组中连续的任务
// 主要是3 的实现方案; 按添加的顺序执行,而不是按请求任务成功返回时间执行;
function useTaksSort() {
    const taskSorting = {
        taskList: [],
        runIndex: 0,
        addIndex: 0,
        run: (task, index) => {
            // 请求任务成功后会按请求的先后顺序把回调添加进稀松数组中,用next执行在数组中连续的任务,
            // 一旦不连续就停止,直到下一个任务成功添加时再用next接着执行连续的任务,
            taskSorting.taskList[index] = task
            taskSorting.next()
        },
        next: () => {
            requestAnimationFrame(() => {
                if (taskSorting.taskList[taskSorting.runIndex]) {
                    taskSorting.taskList[taskSorting.runIndex](taskSorting.runIndex)
                    taskSorting.taskList[taskSorting.runIndex] = null
                    taskSorting.runIndex += 1
                    taskSorting.next()
                } else {
                    // 表示待执行task全部被执行完毕了
                    if (taskSorting.runIndex === taskSorting.addIndex) {
                        // 不清空不重置可以做重发和统计,
                        // 但我选择清空tasklist
                        taskSorting.taskList = []
                        // 不重置指针 使用稀松数组
                        // taskSorting.runIndex = 0
                        // taskSorting.addIndex = 0
                    }
                }
                console.log(taskSorting.runIndex, taskSorting.addIndex)
                console.log(taskSorting.taskList)
            })
        },
        add: (promise) => {
            const index = taskSorting.addIndex;
            taskSorting.addIndex += 1
            return promise.then((res) => {
                const p = new Promise((resolve) => {
                    // 将执行下一阶段then 的控制函数resolve的执行 按任务顺序加入到数组中,
                    // 即使加入时间可能是乱的,但是下标是有序的,依次执行即可
                    taskSorting.run((runIndex) => {
                        resolve({
                            ...res,
                            addIndex: index,
                            runIndex
                        })
                    }, index)
                })

                return p
            })


        }
    }
    return taskSorting
}
const taskSort = useTaksSort();

function addTest() {
    taskSort.add(
        new Promise((resolve) => {
            // 模拟请求 不同返回时间
            const time = parseInt(Math.random() * 5000)
            setTimeout(() => {
                resolve({ time, })
            }, time)
            console.log('add-' + taskSort.addIndex, '延迟:' + time)
        })
    ).then(res => {
        console.log('run-' + res.runIndex, 'add-' + res.addIndex, res.time)
    })

}
document.querySelector("#add").addEventListener('click', addTest)
<button id="add">
    添加失序任务
</button>
#add{
    padding: 20px;
}