首页 > 解决方案 > clearTimeout 不会每次都清除它

问题描述

我正在尝试构建一个carousel

我使用 setInterval 函数解决了这个问题,但问题更严重,所以我决定将它更改为 setTimeout 并递归调用它。

所以我有:

定时器变量

this.timeOut = false;

这两个功能,启用或停止轮播:

stopSlide() {
    console.log('stop', this.timeOut);
    if (this.timeOut) {
        window.clearTimeout(this.timeOut);
        this.timeOut = null;
        delete this.timeOut;
    }
}

startSlide() {
    this.stopSlide();
    const hasMoreThanOneSlide = this.ribbon.querySelectorAll('.pts-desktop-header-ribbon__item').length > 1;
    this.timeOut = hasMoreThanOneSlide ? window.setTimeout(() => this.doPlay(this.play), this.time) : null;
    console.log('start', this.timeOut);
}

而这个播放它(删除一些索引的变量和东西,所以问题不是太大):

doPlay(element) {
    const newScroll = element.classList.contains(BUTTON_LEFT_CLASS) ? 1 : -1;
    const totalItems = this.el.querySelectorAll(`.${BASE_LIST_ITEM}`).length - 1;

    /* Update current */
    this.current++; // this wasn't like this cause actually i can turn +1 or -1 but I don't want to make this question longer

    /* Update visible */
    this.lists.forEach((list) => {
        list.style.transform = `translate(${-this.current * 100}%)`;
    });

    /* Update visible class */
    this.updateCurrentRibbonElement();
    if (this.timeOut) {
        this.stopSlide();
        this.startSlide();  // Calls the setTimeout function again
    } else {
        this.stopSlide();
    }
}

这就是我初始化它的方式:

events.delegate(this.el, `.${BUTTON_CLASS}`, 'click', (e) => {
    this.stopSlide();
    this.doPlay(e.elementTarget);
    this.hideRibbon();
});

/* Start interval */
this.startSlide();

完整的类(Webpack 语法)可以在这里找到:https ://jsfiddle.net/toz4xafu/

所以问题是,有时,当非常快地使用箭头时(强调应用程序)似乎没有清除this.timeOutvar 并且它被多次执行(而不是 7 秒,而是 2-4 秒)

问题是,我怎样才能确保我不会运行超过一个超时?

顺便说一句,有什么方法可以调试正在执行的计时器数量吗?

标签: javascriptrecursionsettimeoutcleartimeout

解决方案


推荐阅读