在PromiseA+规范中,目前是不支持任务中断的,只能是全部执行完,那么我们有时候会碰到这种中止和恢复的需求,怎么办呢?现在我们来默认写一个这样的功能
- 有5个任务,按照循序执行
- 点击暂停按钮,会停止这个序列执行,比如执行到任务3的时候,中断了
- 点击开始按钮,会恢复这个序列执行,从任务3开始执行
具体代码如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button id="start">开始</button>
<button id="pause">暂停</button>
<script>
function processTasks(...tasks) {
let isRunning = false
let i = 0
const result = []
let prom
return {
start(){
return new Promise(async (resolve, reject) => {
if (prom) {
prom.then(resolve, reject)
return
}
isRunning = true
while(i < tasks.length) {
try{
console.log(i, '执行中')
result.push(await tasks[i]())
console.log(i, '执行完成')
}catch(err) {
isRunning = false
reject(err)
prom = Promise.reject(err)
return
}
i++
if (!isRunning && i < tasks.length) {
console.log('执行中断 i= ' + i )
isRunning = false
return
}
}
isRunning = false
resolve(result)
prom = Promise.resolve(result)
})
},
pause(){
isRunning = false
}
}
}
const tasks = []
// 创建带有延迟的5个任务
for (let i = 0 ; i < 5; i++) {
tasks.push(
() => {
return new Promise(resolve => {
setTimeout(() => {
resolve(i)
}, 2000)
})
}
)
}
const processor = processTasks(...tasks)
document.querySelector("#start").addEventListener('click', async () => {
console.log('点击开始')
const results = await processor.start()
console.log('任务执行完成', results)
})
document.querySelector("#pause").addEventListener('click', async () => {
console.log('点击暂停')
processor.pause()
})
</script>
</body>
</html>