//请求(任务)失序问题 的处理
// 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;
}