Javascript 无限期地重复函数,最好不使用setInterval()

Javascript 无限期地重复函数,最好不使用setInterval(),javascript,jquery,loops,Javascript,Jquery,Loops,我正在构建幻灯片放映框架,在找出循环动画功能的最佳方法时遇到了困难,我知道我可以使用setInterval(),但我想知道是否有更好的方法可以在不占用资源的情况下重复它 JAVASCRIPT: class slideShow { constructor(imgDir, dataList) { this.imgDir = imgDir; this.dataList = dataList; this.settings = 0;

我正在构建幻灯片放映框架,在找出循环动画功能的最佳方法时遇到了困难,我知道我可以使用
setInterval()
,但我想知道是否有更好的方法可以在不占用资源的情况下重复它

JAVASCRIPT:

class slideShow {
    constructor(imgDir, dataList) {
        this.imgDir = imgDir;
        this.dataList = dataList;
        this.settings = 0;
        this.imgList = 0;
        this._init();
    }
    _init(){
        $.getJSON(`${this.imgDir}/${this.dataList}.json`, (data)=>{
            this.settings = data.settings;
            this.imgList = data.imgList;
        })
    }
    start(){
        for(let img of this.imgList){
            $(this.settings.selector).fadeOut(this.settings.fadeTime, ()=>{
                $(this.settings.selector).attr("src",`${this.imgDir}/${img}`);
                $(this.settings.selector).fadeIn(this.settings.fadeTime);
            });
        }
    }
}
JSON:

您可以使用
.then()
、jQuery
.promise()
、递归

class slideShow {
    constructor(imgDir, dataList) {
        this.imgDir = imgDir;
        this.dataList = dataList;
        this.settings = 0;
        this.imgList = 0;
        this._init();
    }
    _init(){
        $.getJSON(`${this.imgDir}/${this.dataList}.json`, (data)=>{
            this.settings = data.settings;
            this.imgList = data.imgList;
        }).then(this.start)
    }
    start(){
        for(let img of this.imgList){
            $(this.settings.selector).fadeOut(this.settings.fadeTime, ()=>{
                $(this.settings.selector).attr("src",`${this.imgDir}/${img}`);
                $(this.settings.selector).fadeIn(this.settings.fadeTime);
            });
        }
        $(this.settings.selector).promise()
        .then(() => this.start() /* or this._init() */)
    }
}

一个简单的解决方案是伪递归地从动画最后一步的“完成回调”循环

start() {
    var current = 0;
    (function loop() {
        let img = imgList[current++];
        current %= imgList.length;
        let $sel = $(this.settings.selector);
        $sel.fadeOut(this.settings.fadeTime, () => {
            $sel.attr("src",`${this.imgDir}/${img}`);
            $sel.fadeIn(this.settings.fadeTime, loop); // <-- here
        });
    })();
}
start(){
无功电流=0;
(函数循环(){
设img=imgList[current++];
当前%=imgList.length;
让$sel=$(this.settings.selector);
$sel.fadeOut(this.settings.fadeTime,()=>{
$sel.attr(“src”,`${this.imgDir}/${img}`);

$sel.fadeIn(this.settings.fadeTime,loop);//那么
setInterval()
有什么问题?
setInterval
有很多问题,而且在任何情况下(没有双关语)不应与jQuery动画混合在一起您是否试图等待当前图像完成动画,然后下一个图像在
for..of
循环中开始动画?这不是“真实的”递归,因为事件循环在
之前展开堆栈。然后
回调得到called@Alnitak好的。这个过程应该被称为什么?你的方法可能就是OP在动画部分寻找的。不确定OP是否希望动画按顺序排列?如果是,将替换为
.queue()
$,map()
for
for..of
loopYour
。那么(this.start)
也是错误的,它应该是
。然后(()=>this.start)
因为你有一个未定义的
this
我总是称它为psuedo recursionNo,因为arrow函数将
this
绑定到外部作用域中的任何东西,这是有效的,尽管我不得不添加一个
that=this
。另外,谢谢你指出这个bug。讽刺的是,我刚刚和另一个回答者聊了很久关于
这个
的正确处理,我在自己的回答中没有发现错误:)另一种选择是在
循环
之外取消对选择器和设置值的引用,因为它们是唯一依赖于
这个
的变量。哦,还有
imgDir
start() {
    var current = 0;
    (function loop() {
        let img = imgList[current++];
        current %= imgList.length;
        let $sel = $(this.settings.selector);
        $sel.fadeOut(this.settings.fadeTime, () => {
            $sel.attr("src",`${this.imgDir}/${img}`);
            $sel.fadeIn(this.settings.fadeTime, loop); // <-- here
        });
    })();
}