1

遇到一个有趣的问题。我在进入我的 html ( class="day") 时隐藏了一周中的每一天。通过单击日期,它会通过 AJAX 调用扩展以显示该日期下的所有内容$.post。这一切都运作良好。

我认为用户可能想要一次查看整个星期,所以我有一个按钮 ( id="expander") 来显示所有内容。getSchedule()但是,当我从单击中调用该函数时#expander,它会遍历除函数$.post中的所有内容getSchedule()。然后它循环通过$.post.

$(document).ready(function()
{ 
    $('.day').click(function(){
        pass = $(this).prop('id');
        getSchedule(pass);
    });

    $('#expander').click(function(ex){
            $('.day').each(function(index){
                    pass = $(this).prop('id');
                    getSchedule(pass);
            });
            $('#expander').text('Hide All Days');
        ex.preventDefault();
        return false;       
    });
});

function getSchedule(elementid){
            dow = elementid.substr(-1);
            url = "standarddayofweek.php?d="+dow;
            $theday = $("#"+elementid);
            console.log("The day is "+$theday.prop('id'));
            $.post(url,function(data){
                    $theday.children('.dayschedule').html(data);
                }, "html"
            )
    }

我得到的控制台响应是:

The day is d1 
The day is d2
The day is d3 
The day is d4 
The day is d5 
The day is d6
The day is d7 
XHR finished loading: "http://127.0.0.1/standarddayofweek.php?d=1"
In the post function, the day is d7
XHR finished loading: "http://127.0.0.1/standarddayofweek.php?d=2"
In the post function, the day is d7
XHR finished loading: "http://127.0.0.1/standarddayofweek.php?d=3"
In the post function, the day is d7 
XHR finished loading: "http://127.0.0.1/standarddayofweek.php?d=4"
In the post function, the day is d7 
XHR finished loading: "http://127.0.0.1/standarddayofweek.php?d=5"
In the post function, the day is d7 
XHR finished loading: "http://127.0.0.1/standarddayofweek.php?d=6"
In the post function, the day is d7 
XHR finished loading: "http://127.0.0.1/standarddayofweek.php?d=7"
In the post function, the day is d7 

淡化的 HTML:

<div id="expander">Click me to expand</div>

<div id="d1" class="day">
            <div class="dayschedule"></div>
</div>
<div id="d2" class="day">
            <div class="dayschedule"></div>
</div>

....

<div id="d7" class="day">
            <div class="dayschedule"></div>
</div>

到底是怎么回事?我尝试添加延迟,以查看 AJAX 是否发生得太快,但没有任何改变。

4

4 回答 4

1

Javascript 主要使用单个执行线程运行,请参见此处。这对您的代码意味着什么:

首先,这.each只是一个循环。想象一下 ajax 请求是在 for 循环中发送的。

for(...)
    $.post();

在当前执行停止之前,ajax 回调无法运行。因此,您的代码将遍历所有元素,并按原样进行记录,然后释放线程并且 ajax 回调可以控制。

你应该改变你的程序,这样你就可以得到一个列表或一批内容,这样一个请求只需要几个元素。

于 2012-10-25T22:38:58.070 回答
1

并非所有浏览器都会同步运行,因此async: false不是一个全面的解决方案。但是,将变量本地化为getSchedule()is.

试试这个:

function getSchedule(elementid) {
    var dow = elementid.substr(-1);
    var url = "standarddayofweek.php?d="+dow;
    var $theday = $("#"+elementid);
    console.log("The day is "+$theday.prop('id'));
    $.post(url, function(data) {
        $theday.children('.dayschedule').html(data);
    }, "html");
}

因此,形成了一个包含(正式和非正式)vars 的闭包,当内部函数(ajax 成功处理程序)异步触发时,即使外部函数已经完成并返回,它们仍然可以使用。

于 2012-10-26T00:30:00.197 回答
0

JavaScript 不是多线程的。你的函数必须在异步事情发生之前返回。

通过重复调用$.post而不将执行流程返回给浏览器,您实际上是在排队异步操作,这些操作将在您的代码完成时运行。

例如,如果您的代码永远不会通过永远循环返回,那么您的任何$.posts 都不会被调用。

于 2012-10-25T22:39:03.563 回答
0

感谢@RobertSmith,答案是从 $.post 切换到 $.ajax。我只是改变了:

$.post(url,function(data){
                    $theday.children('.dayschedule').html(data);
                }, "html"
            )

$.ajax({
    url: url,
    async:false,
    success: function(data) {
     $theday.next().children('.dayschedule').html(data);
    }
});

注意async:false; 这就是开关所需要的。

感谢大家的评论!

于 2012-10-26T00:22:14.083 回答