一次调用多个ajax函数,PHP, ajax

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

本文关键字:ajax PHP 函数 调用 一次      更新时间:2023-09-26

我有一个工作的ajax函数,当调用它时将显示当前时间,然后在显示新时间之前setTimeout 10秒。当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的次数越多,函数被调用的次数就越多。我只想让一个函数同时运行,而不是两个,三个,或者更多。我怎么做呢?谢谢。

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>

test .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'/>";

如果我对你的问题理解正确的话,你实际上是在试图实现两件事:

1。只有最后一次ajax调用

在最后一次按键之后,执行一些ajax调用。任何已经很忙的ajax调用都可以跳过,您只对最后一个感兴趣。

这应该不难。当你调用ajax函数时,jQuery返回一个xhr对象。在该xhr对象上,您可以调用abort()方法来取消挂起的调用。(使用jQuery终止Ajax请求)

2。每x次重复ajax调用

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

这可以很容易地通过将setTimeout的结果存储在一个变量中,并在每次设置新的超时之前调用该变量的clearTimeout来解决。这样你就可以取消旧的"队列",然后开始一个新的。

说得够多了,让我们来试着展示一下我更新代码的意思:

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脚本来说,这可能是可以的,但是,最好等到用户完成输入后再进行第一次调用。这叫做debouting,实现起来也不难:http://davidwalsh.name/javascript-debounce-function

创建一个状态变量,用于跟踪ajax调用是否正在运行。最初将其设置为false。然后当函数被调用时,检查状态;如果没有运行,则执行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调用和超时的外部函数将只运行一次,;但是,内部函数将连续每十秒运行一次。