JavaScript 作用域无法访问 setInterval

jus*_*guy 2 javascript scoping

嘿伙计们,有人可以快速帮助我吗?

我在一个函数中有一个幻灯片放映间隔,我想在不使用全局作用域的情况下从另一个函数中清除它,因为我知道这是不好的做法。

有人可以帮忙吗?

function beginSlideshow() {
    var interval = setInterval(function () {
      //Slideshow content here
}

function revertSlideshow() {
    clearInterval(interval);
}
Run Code Online (Sandbox Code Playgroud)

T.J*_*der 6

您必须将计时器句柄存储在某处。:-)

你有很多选择:

模块

您可以使用模块。那么顶级声明就interval不是全局的,它只能被模块访问:

let interval = 0;
export function beginSlideshow() {
    interval = setInterval(function () {
        //Slideshow content here
    }, someValue);
}

export function revertSlideshow() {
    clearInterval(interval);
    interval = 0;
}
Run Code Online (Sandbox Code Playgroud)

在闭包的范围内

与上面的模块类似的概念,但不使用模块:

const { beginSlideshow, revertSlideshow } = (() => {
    let interval = 0;
    function beginSlideshow() {
        interval = setInterval(function () {
            //Slideshow content here
        }, someValue);
    }

    function revertSlideshow() {
        clearInterval(interval);
        interval = 0;
    }

    return { beginSlideshow, revertSlideshow };
})());
Run Code Online (Sandbox Code Playgroud)

在调用者的范围内

beginSlideshow您可以通过返回函数来停止调用,从而使这成为调用者的问题:

function beginSlideshow() {
    const interval = setInterval(function () {
        //Slideshow content here
    }, someValue);
    return () => {
        clearInterval(interval);
    };
}
Run Code Online (Sandbox Code Playgroud)

调用者会这样使用它:

const revertSlideshow = beginSlideShow();
// ...
revertSlideshow();
Run Code Online (Sandbox Code Playgroud)

将其存储在调用者范围中的另一种方法是将其包装在一个类中并将句柄作为数据属性:

class Slideshow {
    interval = 0;

    begin() {
        this.interval = setInterval(/*...*/);
    }

    revert() { // I'd call it "end"
        clearInterval(this.interval);
        this.interval = 0;
    }
}
Run Code Online (Sandbox Code Playgroud)