哈爸学编程 2022-02-06 15:45 采纳率: 100%
浏览 31
已结题

关于《JavaScript高级程序设计》(第4版)第11章 期约与异步函数中期约扩展一节期约取消一节作者介绍“取消令牌”方法的问题

《JavaScript高级程序设计》(第4版)第11章 期约与异步函数中期约扩展一节期约取消一节作者介绍“取消令牌”方法:
es6被认为是激进的,只要期约的逻辑开始执行,就没有办法阻止它执行到完成。作者介绍了实现取消期约的方法是在现有实现基础上提供一种临时性的封装。Kevin Smith提到的“取消令牌”(cancel token)。生成的令牌实例提供了一个接口,利用这个接口可以取消期约;同时也提供了一个期约实例,可以用来触发取消后的操作并求值取消状态。
下面是CancelToken类的一个基本实例:

class CancelToken {
  constructor(cancelFn) {
    this.promise = new Promise((resolve, reject) => {
      cancelFn(resolve);
    });
  }
}

这个类包装了一个期约,把解决方法暴露给了cancelFn参数。这样,外部代码就可以向构造函数中传入一个函数,从而控制什么情况下可以取消期约。这里期约是令牌类的公共成员,因此可以给它添加处理程序以取消期约。
这个类大概可以这样使用:

<button id = "start">Start</button>
<button id = "cancel">Cancel</button>
<script>
class CancelToken {
  constructor(cancelFn) {
    this.promise = new Promise((resolve, reject) => {
      cancelFn(() => {
        setTimeout(console.log, 0, "delay cancelled");
        resolve();
      });
    });
  }
}
const startButton = document.querySelector('#start');
const cancelButton = document.querySelector('#cancel');
function cancellableDelayedResolve(delay) {
  setTimeout(console.log, 0, "set delay");
  return new Promise((resolve, reject) => {
    const id = setTimeout(() => {
      setTimeout(console.log, 0, "delayed resolve");
      resolve();
    }, delay);
    const cancelToken = new CancelToken((cancelCallback) => cancelButton.addEventListener("click", cancelCallback));
    cancelToken.promise.then(() => clearTimeout(id));
  });
}
startButton.addEventListener("click", () => cancellableDelayedResolve(3000));
</script>

问题:
不用取消令牌,将代码改为:

<button id = "start">Start</button>
<button id = "cancel">Cancel</button>
<script>
const startButton = document.querySelector('#start');
const cancelButton = document.querySelector('#cancel');
function cancellableDelayedResolve(delay) {
  setTimeout(console.log, 0, "set delay");
  return new Promise((resolve, reject) => {
    const id = setTimeout(() => {
      setTimeout(console.log, 0, "delayed resolve");
      resolve();
    }, delay);
    cancelButton.addEventListener("click", () => {
      clearTimeout(id);
      console.log("delay cancelled");
    });
  });
}
startButton.addEventListener("click", () => cancellableDelayedResolve(3000));
</script>

这样也是可以实现取消期约的,那为什么要用令牌呢?

  • 写回答

3条回答 默认 最新

  • CSDN专家-showbo 2022-02-06 16:32
    关注

    最重要的代码就clearTimeout(id);这句,题主自己写的这个感觉还简单明了些~

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 2月14日
  • 已采纳回答 2月6日
  • 创建了问题 2月6日

悬赏问题

  • ¥100 为什么这个恒流源电路不能恒流?
  • ¥15 有偿求跨组件数据流路径图
  • ¥15 写一个方法checkPerson,入参实体类Person,出参布尔值
  • ¥15 我想咨询一下路面纹理三维点云数据处理的一些问题,上传的坐标文件里是怎么对无序点进行编号的,以及xy坐标在处理的时候是进行整体模型分片处理的吗
  • ¥15 CSAPPattacklab
  • ¥15 一直显示正在等待HID—ISP
  • ¥15 Python turtle 画图
  • ¥15 关于大棚监测的pcb板设计
  • ¥15 stm32开发clion时遇到的编译问题
  • ¥15 lna设计 源简并电感型共源放大器