首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >循环中的同步Ajax -阻塞问题

循环中的同步Ajax -阻塞问题
EN

Stack Overflow用户
提问于 2021-03-09 17:28:25
回答 1查看 26关注 0票数 0

我有一个对象I列表,需要将每个对象I发送到后端进行处理。后端处理是时间密集型、资源密集型和容易失败的过程。因此,我希望在浏览器上呈现后端处理结果的情况下,每次处理一个项目。

我的代码如下(简化以便于阅读):

代码语言:javascript
复制
// initialize variables:
var items = ['obj-1', 'obj-2', 'obj-3', ...],
var messageBoard = $('#message-board-id');

// append start message to board:
messageBoard.append('Starting backend job');

// iterate over each item:
for (var item of items) {

  // send sync ajax request:
  $.ajax({
    url : 'backend_process_url/',
    type : 'POST',
    aysnc : false,
    data : {
      item : item,
    },
    
    // handle successful backend jobs:
    success : function(response) {
      messageBoard.append('Job successful!');
      ...
    }  

    // handle failed backend jobs:
    error : function(response) {
      messageBoard.append('Job failed!');
      ...
    }
  }

}

messageBoard.append('All jobs complete');

问题是,同步ajax请求会阻塞整个循环--这意味着在所有后端作业完成之前,不会向messageBoard追加任何消息。所需的行为是将消息显示为完成每个项的后端作业。

我对承诺的理解是有限的,使用它们的尝试也失败了--如果这是一个合理的解决方案,我们将非常感谢你的帮助。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-03-09 18:50:12

如果下一个Ajax请求是在第一个Ajax的success上启动的呢?

您必须将Ajax代码放在一个命名函数中,以便在success上再次调用它。您甚至可以在每个请求之间插入一个延迟(这里我使用了800 in )。关键是检查与items长度相比的“作业”索引。

下面是一个使用JSON PlaceHolder.com的例子..。在那里得到的反应非常快。但是用你更长的要求试试吧。我很肯定会很好的。

代码语言:javascript
复制
// initialize variables:
var items = [{userId:1},{userId:3},{userId:5},{userId:7},{userId:9}];
var messageBoard = $('#message-board-id');

function runAjax(reqIndex=0){

  // send async Ajax request:
  $.ajax({
    url : 'https://jsonplaceholder.typicode.com/posts',
    type : 'POST',
    data : items[reqIndex],

    // handle successful backend jobs:
    success : function(response) {
      messageBoard.append(`Job #${reqIndex} successful!<br>`);
      console.log(`Job #${reqIndex}`,response)

      // Get the next index if still lees than the items length
      reqIndex = (reqIndex >= items.length-1) ? null : reqIndex+1
      
      // If not null
      if(reqIndex){
        setTimeout(runAjax(reqIndex),800)
      }else{
        messageBoard.append('All jobs complete');
      }
    },
    // handle failed backend jobs:
    error : function(response) {
      messageBoard.append('Job failed!');
    }
  })
}

// append start message to board:
messageBoard.append('Starting backend job<br>');

// Start with the first request to make, using the index 0 of the items array.
runAjax()
代码语言:javascript
复制
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div id="message-board-id"></div>

CodePen

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66551876

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档