【问题标题】:Javascript - AJAX request inside loopsJavascript - 循环内的 AJAX 请求
【发布时间】:2023-03-09 10:05:01
【问题描述】:

我正在使用 jQuery 发送 AJAX 请求,从服务器检索数据。

然后将该数据附加到一个元素。这应该发生 5 次,但它总是随机发生 3、4 或 5 次。基本上,有时循环会跳过 AJAX 请求,但大多数时候它会捕获它。我如何确保它每次完成请求五次?以及这种跳过 AJAX 请求的随机行为背后的原因是什么?(旁注。我检查了请求错误,但它从未提醒过请求失败)

这是我的 JS:

while (counter < 6) {
    $.ajax({
        url:'http://whisperingforest.org/js/getQuote.php',
        async: false,
        dataType: 'jsonp',
        success:function(data){
            $('.quoteList').append('<li>' + data +'</li>');
            totalQuotes++;
        }
    });
    counter++;
}

附:这发生在按下按钮时。

【问题讨论】:

  • 网络标签上有什么?是否发送了 5 个 http 请求?
  • 为什么要发出 6 个请求,而不是在一个请求中获取所需的所有数据,然后将其拆分为 6 个列表项?
  • 刚刚检查了网络选项卡(不知道这存在:P)...它发出所有请求,但大约 30% 的时间会收到“500 内部服务器错误”。 .. && 我提出 6 个单独的请求,因为.. 这是我第一次使用 AJAX,我不知道如何从多行中提取信息,而不是从单行的回显字符串中提取信息。
  • 看来您已经发现了问题。
  • 在多行的事情上,假设你在服务器端调用json_encode,只需传入一个非关联数组,它就会返回一个JS数组的JSON,例如json_encode(array(1,2,3)) 将返回 [1,2,3],然后您可以在客户端进行迭代。

标签: javascript jquery ajax


【解决方案1】:

不要同步进行。使用回调。这是一个演示:http://jsfiddle.net/y45Lfupw/4/

<ul class="quoteList"></ul>
<input type="button" onclick="getData();" value="Go Get It!">

<script>
var counter = 0;

window.getData=function()
{
    /* This IF block has nothing to do with the OP. It just resets everything so the demo can be ran more than once. */
    if (counter===5) {
        $('.quoteList').empty();
        counter = 0;
    }

    $.ajax({
        /* The whisperingforest.org URL is not longer valid, I found a new one that is similar... */
        url:'http://quotes.stormconsultancy.co.uk/random.json',
        async: true,
        dataType: 'jsonp',
        success:function(data){
            $('.quoteList').append('<li>' + data.quote +'</li>');
            counter++;
            if (counter < 5) getData();
        }
    });
}
</script>

async设置为false会阻塞主线程(负责 执行 JavaScript,渲染屏幕等)并等待 XHR 完成。

这几乎总是一个糟糕的主意。用户不喜欢反应迟钝 用户界面。 (https://stackoverflow.com/a/20209180/3112803)

只需在stackoverflow 中搜索ajax async: false,您就会发现很多很好的解释。每个人都会劝阻你不要使用async:false。这是一个很好的解释:https://stackoverflow.com/a/14220323/3112803

【讨论】:

  • 我试了一下确切的代码,但不幸的是它对我没有任何作用,甚至没有显示一个报价。我不明白为什么?我尝试在 ajax 调用之前和之后放置一个 alert('works'),两者都触发了......但没有附加任何内容?
  • 哎呀!抱歉,我在您编辑之前逐字复制了您的代码,并且错过了自己添加数据类型>_
【解决方案2】:

当您执行异步请求循环并检测所有 ajax 请求是否完成时,jQuery 提供了非常有趣的方法。可以通过使用

var users=["a","b","c","d","e","f","g","h"];

var async_request=[];
var responses=[];
for(i in users)
{
    // you can push  any aysnc method handler
    async_request.push($.ajax({
        url:'', // your url
        method:'post', // method GET or POST
        data:{user_name: users[i]},
        success: function(data){
            console.log('success of ajax response')
            responses.push(data);
        }
    }));
}


$.when.apply(null, async_request).done( function(){
    // all done
    console.log('all request completed')
    console.log(responses);
});

这里 $.when 提供了一种基于零执行回调函数的方法 或更多对象,通常是表示异步的延迟对象 事件。

apply() 将数组元素转换为不同的参数 函数

$.done 毕竟是异步调用函数。请求是 完成。

【讨论】:

  • JS 的.apply 不是$.apply
  • 请注意:当 ajax 调用之一失败时,也会调用 .done()。这并不总是您希望发生的。
【解决方案3】:

你可以像这样使用 ES6 async/await Promises

function fromServer(){
  return new Promise((resolve, reject) => {
     $.ajax({
        url:'http://whisperingforest.org/js/getQuote.php',
        async: false,
        dataType: 'jsonp',
        success:function(data){
             resolve(data)
        }
    });
  })
}
var totalQuotes = 0;
async function domManipulation(){
    while (counter < 6) {
        var data = await fromServer();
        $('.quoteList').append('<li>' + data +'</li>');
        totalQuotes++;
    }
}

domManipulation()

JSFIDDLE

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-08-08
    • 2010-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-15
    • 2019-03-24
    相关资源
    最近更新 更多