一次调用超过 1 个 ajax 函数,PHP,AJAX

More than 1 ajax function being called at once, PHP, AJAX

我有一个有效的 ajax 函数,调用它时会显示当前时间,然后在显示新时间之前设置超时十秒。当在文本输入上触发 onkeyup 时,我调用了这个函数,它起作用了。但是有一个小问题。如果我在调用 ajax 函数后在文本输入中键入其他内容,它将调用另一个 ajax 函数,并在 ajax 处有两个函数 运行同时。例如:

如果触发时第一个ajax函数在3:00:00调用,第二个ajax函数在3:00:05调用,则说明有现在两个 ajax 功能同时 运行。第一个 ajax 函数将在 10 秒 setTimeout 后在 3:00:10 再次触发,第二个 ajax 函数将在其 10 秒 setTimeout 后在 3:00:15 再次触发.所以你在文本输入中触发onkeyup的次数越多,这个函数就会被调用的次数越多。我只希望自身的 1 个函数同时为 运行,而不是 2、3 或更多。我怎么做?谢谢。

ajax.php

<script type = "text/javascript"> 

function timeoutAjax(url,type,theName,id,timeout) {

      $.ajax({
           type: "POST",
           url: url,
           data: { select: $(type+'[name='+theName+']').val()},
           error: function(xhr,status,error){alert(error);},
           success:function(data) {
             document.getElementById( id ).innerHTML = data;
             setTimeout(function() { timeoutAjax(url,type,theName,id,timeout); }, timeout);
           }

      });

}

</script>

test1.php

<?php

include('ajax.php');

echo "<input type = 'text' name = 'name' onkeyup = 'timeoutAjax(\"test2.php\",\"input\",\"name\",\"output1\",\"10000\")'>";
echo "<div id = 'output1'/>";

?>

test2.php

<?php

$time = date('H:i:s A');
echo $time;

?>

************更多详情************

echo "<input type = 'submit' name = 'name1' value = 'Reset' onclick = 'timeoutAjax(\"test2.php\",\"input\",\"name1\",\"output1\",\"10000\")'>";
echo "<input type = 'submit' name = 'name2' value = 'Reset' onclick = 'timeoutAjax(\"test2.php\",\"input\",\"name2\",\"output2\",\"10000\")'>";

echo "<div id = 'output1'/>";
echo "<div id = 'output2'/>";

创建一个状态变量来跟踪 ajax 调用是否为 运行ning。最初将其设置为 false。然后当函数被调用时,检查状态;如果不是 运行ning 执行 ajax 调用,将状态变量设置为 true,然后在成功回调中再次将其设置为 false:

<script type = "text/javascript">
    //Create the status var (This may not be the best place to initialize it). Use your best judgement.
    var running = false;

    function timeoutAjax(url,type,theName,id,timeout) {


        //Check if there is an ajax call in progress. If not execute one.
        if(!running)
        {
            //Change the status to running
            running = true;
            console.log('In if')
            console.log(running)
            $.ajax({
                type: "POST",
                url: url,
                data: { select: $(type+'[name='+theName+']').val()},
                error: function(xhr,status,error){alert(error);},
                success:function(data) {
                    document.getElementById( id ).innerHTML = data;
                    setTimeout(function() {

                        //Set the status to false for the inner function call
                        running = false;
                        timeoutAjax(url,type,theName,id,timeout);
                        //Set the status to true for the outer function call
                        runnng = true;
                    }, timeout);
                }

            });

        }
    }

</script>

外层函数触发第一个ajax调用,超时只会运行一次,;但是,内部函数将连续每十秒 运行。 我希望这对你有用,如果是这样,请接受这个答案。谢谢

如果我对你的问题的理解正确,那么你实际上是想在这里实现两件事:

1.仅最后 ajax 调用

最后一次击键后,进行一些 ajax 调用。任何已经占线的 ajax 呼叫都可以跳过,您只对最后一个感兴趣。

这应该不难。 jQuery returns 调用 ajax 函数时的 xhr 对象。在那个 xhr 对象上,您可以调用 abort() 方法来取消挂起的调用。 (Abort Ajax requests using jQuery)

2。每 x 次重复 ajax 调用

现在您在 ajax 成功函数中设置了一个 timeout,它将在给定时间后重复调用。问题是,当你从外部再次调用你的 ajax 函数时(所以我的意思不是递归,而是通过另一个按键或其他东西)你只会创建另一个无限的 ajax 调用字符串。一段时间后,您将遇到大量呼叫队列,这些呼叫将开始重叠并耗尽您的所有资源。

这很容易解决,方法是将 setTimeout 的结果存储在一个变量中,并在每次设置新超时之前对该变量调用 clearTimeout。这样你就可以取消旧的 'queue' 并开始一个新的。

英语太烂了,让我们尝试通过更新您的代码来说明我的意思:

function timeoutAjax(url, type, theName, id, timeout, trigger) {
    // abort pending calls
    if (trigger.xhr) {
        trigger.xhr.abort();
    }
    // abort queued calls
    clearTimeout(trigger.queued);

    // make the call
    trigger.xhr = $.ajax({
        type: "POST",
        url: url,
        data: {
            select: $(type + '[name=' + theName + ']').val()
        },
        error: function (xhr, status, error) {
            alert(error);
        },
        success: function (data) {
            document.getElementById(id).innerHTML = data;
            // queue a new call
            trigger.queued = setTimeout(function () {
                timeoutAjax(url, type, theName, id, timeout, trigger);
            }, timeout);
        }

    });

}

还有一个旁注。即使我对您的代码进行了更改,您仍将中止并在每次击键时进行新的 ajax 调用。中止 ajax 调用并不自动意味着您的服务器停止处理请求,具体取决于您使用的后端。对于您现在使用的简单 php 脚本,它可能没问题,但是,最好等到用户完成输入后再进行第一次调用。这称为去抖动,也不是很难实现:http://davidwalsh.name/javascript-debounce-function