JS 中,串行异步任务的取消是否有更好的处理方式

查看 26|回复 1
作者:dvsilch   
最近遇到的业务场景:
[ol]
  • 用户输入时进行初始化,初始化过程中包含了异步任务的串行
  • 初始化过程中,不阻塞用户输入
    [/ol]
    如果用户输入时上一次的初始化还没结束,就会出现多次初始化的并行。我目前的处理方式是初始化开始时记下当前状态,每结束一个串行的异步任务,都进行一次状态比对。简化后的代码如下:
    /**
    * @type {number | undefined}
    */
    let state = undefined
    /**
    * @param {number} ms
    * @returns {Promise}
    * @description sleep for ms milliseconds to simulate async task
    */
    function sleep(ms) {
      return new Promise((resolve) => setTimeout(resolve, ms))
    }
    /**
    * @returns {Promise}
    * @description init async task
    */
    async function init() {
      const current = Date.now()
      state = current
      await sleep(500)
      if (state !== current) {
        console.warn(`state ${current} init: canceled`)
        return
      }
      await sleep(500)
      if (state !== current) {
        console.warn(`state ${current} init: canceled`)
        return
      }
      console.log(`state ${current} init: done`)
      state = undefined
    }
    但我感觉这种做法不太合理,虽然上面用当前时间戳模拟了状态,但实际上业务场景中可能会出现某几次用户输入一致,所以状态一致,进而导致这几次输入执行的初始化过程无法正常中断。像 C#中有 CancellationToken 可以直接调用 Cancel 取消异步任务。不知道 JS 是否拥有类似的设计,或者对于这类业务场景有更好的处理方式?
  • chenliangngng   
    为什么要用时间戳,直接存储状态不就可以了
    不论是 promise 和 ajax 都可以取消
    您需要登录后才可以回帖 登录 | 立即注册

    返回顶部