clearInterval 在一种情况下失败,但在另一种情况下不会失败



我正在运行一个函数来检查数据库条目是否存在。

在我的页面加载中,我检查元素是否存在,如果存在,我使用 setInterval 来运行函数。这样:

if ( $('#encoding').length ) {
    console.log("auto_update start");
    var update = setInterval(auto_update, 12000);
}

然后在我的auto_update函数中发生这种情况

function auto_update() {
    console.log("auto_update running");
    $.ajax({
        type: 'POST',
        url: ajaxurl,
        data: {
            action: "dhf_ajax_router",
            perform: "dhf_check_status", // the function we want to call
            post_id: $('#post_id').val(),
            nonce: $('#dhf-video-meta-nonce').val()
        },
        success: function(response) {
            if ( response === "continue" ) {
                console.log("still encoding");
            } else {
                clearInterval(update);
                console.log("complete " + response);
            }
        }
    });
}

问题是,如果$('#encoding')在开始时没有出现在页面上,并且是由用户在以下位置手动触发的:

$(document).on("click", ".run_encode", function(){
        // doing the necessary stuff here.
        if ( response === "sent" ) {
                // more stuff
                var update = setInterval(auto_update, 12000);
        } 
}); // end .run_encode

然后clearInterval(update)不起作用,最终陷入无限循环。

我不知道为什么。在这两种情况下都设置了名称update的间隔,那么为什么在第二种情况下清除它不起作用呢?

在函数中声明update变量。另一个函数无法访问它的值。

jfriend00 就如何解决它给出了广泛的答案。我会走另一条路:使用 setTimeout .无论如何,还是建议这样做,因为 AJAX 调用不会占用恒定时间,而是每次都会变化。想象一下,由于网络故障,它需要超过 12 秒:你会被搞砸的。

您必须确保共享变量update在两个作用域中都可用。 这意味着它要么需要位于公共父作用域中,要么需要将update变量设置为全局变量,以便它不会超出作用域。

最有可能的是,您声明update位于终止的函数中,当该函数终止时,update变量超出范围并被销毁。

你可以使变量的初始设置进入全局范围(所以当你像这样调用clearInterval()时它仍然可用:

$(document).on("click", ".run_encode", function(){
    // doing the necessary stuff here.
    if ( response === "sent" ) {
            // more stuff
            window.update = setInterval(auto_update, 12000);
    } 
}); // end .run_encode

或者,你可以将update变量声明为全局变量,首先将其放在全局级别(在任何函数之外),然后此代码将只修改全局变量:

var update;
$(document).on("click", ".run_encode", function(){
        // doing the necessary stuff here.
        if ( response === "sent" ) {
                // more stuff
                update = setInterval(auto_update, 12000);
        } 
}); // end .run_encode

最新更新