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

nde*_*eau 2 ajax jquery 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();
    }
});
Run Code Online (Sandbox Code Playgroud)

我想让它在将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();
    }
});
Run Code Online (Sandbox Code Playgroud)

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

更新2

最后,我可以设法得到延迟,但我意识到在延迟后仍然将请求发送到服务器,即使在两者之间触发了mouseleave事件......

我可以找到一个解决方法.这是完全不同的.延迟不再起作用,但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();
    }
});
Run Code Online (Sandbox Code Playgroud)

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

感谢大家.

Bla*_*ger 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)
    },
...
Run Code Online (Sandbox Code Playgroud)

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

通过将$.ajax(...)有相反,你告诉JavaScript来(1)立即运行和(2)设置的第一个参数不管AJAX功能的回报 -这,根据文档,是jqXHR对象,setTimeout不能做任何事情用.

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


Ant*_*ist 5

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

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


Ric*_*gan 5

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

你在这里做的不是 - 你正在调用函数作为第一个参数setTimeout().因此,它不会等待.

你要:

setTimeout(function () {
    $.ajax({});
}, 5000);
Run Code Online (Sandbox Code Playgroud)

这就像之间的区别:

setTimeout(foo, 1000);
Run Code Online (Sandbox Code Playgroud)

setTimeout(foo(), 1000);
Run Code Online (Sandbox Code Playgroud)