为什么setTimeout不能用于AJAX请求?

时间:2012-06-18 15:33:22

标签: jquery ajax wait

我有这个非常简单的jQuery函数:

$(".milestone-in-tree").live({
    mouseenter: function() {
        setTimeout(
        $.ajax({
            type: "GET",
            url:"/projects/pmnodes/" + $(this).data("pmnode") + "/addbuttons.js"
        }),5000)
    },
    mouseleave: function() {
        $(".grid-btn").delay(800).remove();
    }
});

我希望在将AJAX请求发送到服务器之前等待5秒,但它不会等待,它只是立即发送它。为什么呢?

更新

感谢您的所有反馈。我改变了所有答案中建议的功能:

$(".milestone-in-tree").live({
    mouseenter: function() {
        var node = $(this).data("pmnode")
        setTimeout(function() {
        $.ajax({
            type: "GET",
            url:"/projects/pmnodes/" + node + "/addbuttons.js"
        }),5000});
    },
    mouseleave: function() {
        $(".grid-btn").delay(800).remove();
    }
});

但我仍然没有拖延。有什么我误解了吗? PS:我创建了节点变量,因为我忽略了一个原因,在SetTimeout匿名函数中不再可以访问$(this)。

更新2

最后,我可以设法得到延迟,但我意识到请求仍然在延迟后发送到服务器,即使鼠标间隔事件已经被触发......

我可以找到解决方法。这是完全不同的。延迟不再起作用,但ajax请求在mouseleave事件中被中止,这是我真正需要的。对于可能感兴趣的人,这是代码:

var button_request;
$(".milestone-in-tree").live({
    mouseover: function() {
        var node = $(this).data("pmnode");
        button_request = $.ajax({
                        type: "GET",
                        url:"/projects/pmnodes/" + node + "/addbuttons.js"
                    });
        setTimeout(function() {button_request;},5000)
    },
    mouseleave: function() {
        if (button_request) {
            button_request.abort();
            button_request = null;
                }
        $(".grid-btn").remove();
    }
});

当然可以删除setTimeout(因为它不起作用......)但是为了清楚起见我留下了它。

谢谢大家。

7 个答案:

答案 0 :(得分:6)

试试这个:

$(".milestone-in-tree").live({
    mouseenter: function() {
        var pmnode = $(this).data("pmnode"); // cache the data in a variable
        setTimeout( function() { // this function(){...} wrapper is necessary
            $.ajax({
                type: "GET",
                url:"/projects/pmnodes/" + pmnode + "/addbuttons.js"
            })
        },5000)
    },
...

setTimeout()调用的第一个参数需要是一个字符串(你真的,真的不应该这样做)或一个自包含的函数对象。

通过将$.ajax(...)放在那里,你告诉JavaScript(1)立即运行它,(2)将第一个参数设置为无论ajax函数返回 - 其中,根据{{​​3}},是setTimeout无法执行任何操作的jqXHR对象。

养成每次使用匿名function(){...}作为setTimeout()setInterval()的第一个参数的习惯,你会没事的。

答案 1 :(得分:5)

您正在调用$.ajax()函数,并将该调用返回的内容传递给setTimeout()。您需要将其包装在匿名函数中:

setTimeout(function() {
    $.ajax({
        type: "GET",
        url:"/projects/pmnodes/" + $(this).data("pmnode") + "/addbuttons.js"
    })
},5000);

答案 2 :(得分:5)

setTimeout()要么接受一串Javascript代码eval(非常糟糕的做法,可能会添加),一个在指定后调用的函数引用时间。

你在这里做的事既不是---你把一个函数称为setTimeout()的第一个参数。因此,它不会等待。

你想:

setTimeout(function () {
    $.ajax({});
}, 5000);

这就像是:

之间的区别
setTimeout(foo, 1000);

setTimeout(foo(), 1000);

答案 3 :(得分:2)

您正在立即调用它,将其置于函数回调中:

   setTimeout( function() {
    $.ajax({
        type: "GET",
        url:"/projects/pmnodes/" + $(this).data("pmnode") + "/addbuttons.js"
    })
   } ,5000)

答案 4 :(得分:1)

包装一个匿名函数:

setTimeout(function(){
        $.ajax({
            type: "GET",
            url:"/projects/pmnodes/" + $(this).data("pmnode") + "/addbuttons.js"
        });
},5000)

答案 5 :(得分:1)

您传入的代码实际上正在执行,如果您想在第一个参数内运行代码,则需要将其包装在函数中:

$(".milestone-in-tree").live({
    mouseenter: function() {
        setTimeout(
function(){
        $.ajax({
            type: "GET",
            url:"/projects/pmnodes/" + $(this).data("pmnode") + "/addbuttons.js"
        }),5000);
}
    },
    mouseleave: function() {
        $(".grid-btn").delay(800).remove();
    }
});

答案 6 :(得分:1)

需要function()

setTimeout(function(){
        $.ajax({
        ...
}, 5000)