繁体   English   中英

如何在 if 条件下不使用 setTimeout 重复 function?

[英]How do I not repeat function with setTimeout with if condition?

我有一个 function,它基本上从 txt 文件中获取数据,对其进行解析,并将解析后的数据放入 HTML 标签中。 此 function 设置为超时 500。

如果自上次 function 迭代以来文件中的数据没有更改,我怎么能不在 HTML 标记中放置相同的数据? 因为我不希望它执行相同的任务 417 次哈哈。 截屏

我试过这个,但看起来变量在 function 的每次迭代后都会被删除。

function loadTxt() {
    jQuery.get('http://localhost:8000/np/nowPlaying.txt', function (data) {
        var nowPlaying = data.split("\n");
        if (p != data) {
            var p = data;
            var i = 0;
            document.getElementById('track').innerHTML = nowPlaying[i++];
            document.getElementById('by').innerHTML = nowPlaying[i++];
            document.getElementById('artist').innerHTML = nowPlaying[i++];
            if (nowPlaying.length == 5) {
                document.getElementById('from').innerHTML = nowPlaying[i++];
                document.getElementById('album').innerHTML = nowPlaying[i++];
            }
            console.log(p)
        }
    })
    var t = setTimeout(loadTxt, 500);
}

问题是var p是在loadTxt中定义的,所以每次执行loadTxt时,都会得到该变量的一个新实例。 相反,在 function 之外定义p ,因此当loadTxt时,它将始终访问相同的变量实例。

其他一些可以改进的地方:

  • 只有当您已经知道数据不同时才需要调用split 所以在第一个if块内

  • 为避免您收到多个待处理的 get-requests,在可能是慢速连接的情况下,在您确定当前 get-request 返回响应之前不要启动下一个setTimeout 所以将它移到get回调 function 中。

  • 您的代码不包括t的声明。 就目前而言,您似乎将其隐式定义为全局变量,然后从不使用它。 所以把它们放在一起。

  • 使用更具描述性的变量名称。 p完全没有意义。

  • 当您使用 jQuery 时,请充分使用它,避免冗长的document.getElementById ...

建议代码:

jQuery(function () { // Only execute when the DOM has loaded
    let displayedData; // Define only once (this is your `p`)
    // Get a reference to the 5 elements of interest, only once
    let $elems = jQuery("#track, #by, #artist, #from, #album");
    
    function loadTxt() {
        jQuery.get('http://localhost:8000/np/nowPlaying.txt', function (data) {
            if (displayedData != data) {
                displayedData = data;
                data.split("\n").forEach((txt, i) => $elems.eq(i).text(txt));
            }
            // Only launch setTimeout when you have the response
            setTimeout(loadTxt, 500);
        });
    }
    
    loadTxt(); // initial start
});

您的代码还有另一个问题:如果以前的数据有五个值(包括专辑),但最新的只有三个,则其余两个值不会更改。 这可能不是你想要的。 也许在这种情况下,您希望清除剩余的两个元素。

如果是这样,请将您的代码更改为:

jQuery(function () { // Only execute when the DOM has loaded
    let displayedData; // Define only once (this is your `p`)
    // Get a reference to the 5 elements of interest, only once
    let $elems = jQuery("#track, #by, #artist, #from, #album");
    
    function loadTxt() {
        jQuery.get('http://localhost:8000/np/nowPlaying.txt', function (data) {
            if (displayedData != data) {
                displayedData = data;
                let props = data.split("\n");
                $elems.each((i, elem) => $(elem).text(props[i] || ""));
            }
            // Only launch setTimeout when you have the response
            setTimeout(loadTxt, 500);
        });
    }
    
    loadTxt(); // initial start
});

或者你可以试试这个(使用闭包,保留你以前的值);

function loadTxt() {
    var p = null; // define variable to store previous value
    return () => {
        jQuery.get('http://localhost:8000/np/nowPlaying.txt', function (data) {
            var nowPlaying = data.split("\n");
            if (p != data) {
                p = data; // update previous value
                var i = 0;
                document.getElementById('track').innerHTML = nowPlaying[i++];
                document.getElementById('by').innerHTML = nowPlaying[i++];
                document.getElementById('artist').innerHTML = nowPlaying[i++];
                if (nowPlaying.length == 5) {
                    document.getElementById('from').innerHTML = nowPlaying[i++];
                    document.getElementById('album').innerHTML = nowPlaying[i++];
                }
                console.log(p)
            }
        })
    }
}

var loadTxtWhenChanged = loadTxt();
var t = setInterval(loadTxtWhenChanged, 500);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM