任务队列的中断和恢复

Huy大约 2 分钟javascriptjavascript

实现一个任务队列管理工具:依次顺序执行一系列任务,并在所有任务全部完成后可以获得每个任务的执行结果。

需要返回俩个方法:start 方法用于启动任务,pause 方法用于暂停任务。

每个任务具备原子性,即不可中断,只能在俩个任务之间中断。

/**
 * @description: 任务队列的中断和恢复
 * @params {...Function} tasks 任务列表,每个任务列表无参数、异步函数
 * @return {*}
 */
function processTasks(...tasks) {
  const result = []

  let isRunning = false
  let i = 0

  return {
    start() {
      return new Promise(async (resolve) => {
        if (isRunning) {
          return
        }

        isRunning = true

        while (i < tasks.length) {
          console.log(`开始执行第${i}个任务`)
          const res = await tasks[i]()
          result.push(res)
          console.log(`${i}个任务执行完毕`)
          i++

          if (!isRunning) return // 每次结束任务进行判断, 若被中断了, 则提前退出, 此时并不执行 resolve, 转态依旧挂起, 异步阻塞
        }

        isRunning = false
        resolve(result)
      })
    },
    pause() {
      isRunning = false
    },
  }
}

验证示例:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>任务队列管理</title>
  </head>
  <body>
    <button id="begin">开始任务</button>
    <button id="pause">暂停任务</button>

    <script>
      function processTasks(...tasks) {
        const result = []

        let isRunning = false
        let i = 0

        return {
          start() {
            return new Promise(async (resolve) => {
              if (isRunning) {
                return
              }

              isRunning = true

              while (i < tasks.length) {
                console.log(`开始执行第${i}个任务`)
                const res = await tasks[i]()
                result.push(res)
                console.log(`${i}个任务执行完毕`)
                i++

                if (!isRunning) return // 每次结束任务进行判断, 若被中断了, 则提前退出, 此时并不执行 resolve, 转态依旧挂起, 异步阻塞
              }

              isRunning = false
              resolve(result)
            })
          },
          pause() {
            isRunning = false
          },
        }
      }

      // ------- 测试用例 -------
      const tasks = []
      for (let i = 1; i < 5; i++) {
        tasks.push(() => {
          return new Promise((resolve) => {
            setTimeout(() => {
              resolve(i)
            }, 2000)
          })
        })
      }

      const processor = processTasks(...tasks)

      begin.onclick = async () => {
        console.log('点击开始')
        const result = await processor.start()
        console.log('任务完成', result)
      }

      pause.onclick = () => {
        console.log('点击暂停')
        processor.pause()
      }
    </script>
  </body>
</html>
Loading...