【问题标题】:Best practice for multiple AJAX API calls that require a response from the previous call?需要前一个调用响应的多个 AJAX API 调用的最佳实践?
【发布时间】:2016-08-19 15:16:21
【问题描述】:

我正在开发一个内部页面,该页面允许用户上传包含资源和日期的 CSV,并让该页面将这些资源的所有计划信息添加到我们的管理软件中。有一个相当不错的 API 可以做到这一点,而且我有一个工作模型,但它似乎......笨拙。

对于每个资源,我必须启动一个新会话,然后创建一个新的预留,然后添加资源,然后确认预留没有被阻止,然后提交预留。大多数调用都会返回我在流程中下一步需要的变量,因此每个调用都依赖于之前的 ajax 调用。

目前我正在通过类似这样的嵌套 ajax 调用来执行此操作:

$.ajax('startnewsession').then($.ajax('createreservation').then('etcetc'))

虽然这行得通,但我觉得必须有一种更简单或更“正确”的方式来做到这一点,无论是为了更简洁的代码还是为了适应能力。

【问题讨论】:

  • 我通常将我的数据分成块数组。然后,发送第一个块(索引为 0),并在$.ajaxcomplete 事件上移动到下一个块(索引)。在您的场景中,您可能想看看$.when
  • 如果您必须依赖上一个 ajax 调用的输出来进行下一个 ajax 调用,那么我认为 $.when 可能无济于事。如果你总是有这一系列的ajax调用,那么我们可以将所有逻辑包装在单个服务中以避免往返吗?

标签: javascript jquery ajax rest


【解决方案1】:

假设您无法更改正在与之通信的 API,您所做的是正确的。

如果您需要前一个的响应数据用于下一个,那么确实没有办法绕过必须执行某种嵌套的 ajax 调用。然而,Promise (.then) 使它比必须进行回调更漂亮。

正确的解决方案(如果可能的话)当然是以这样一种方式实现您的 API,即它需要更少的从客户端到服务器的往返。考虑到在创建预订的协商过程中的每个步骤之间没有用户输入,您的 API 应该能够完成创建预订的整个流程,而无需联系客户端,直到需要用户提供更多输入。

请记住在每个 ajax 调用之间进行一些错误处理,以防它们失败 - 您不想使用来自先前失败请求的损坏数据开始创建后续 API 调用。

var baseApiUrl = 'https://jsonplaceholder.typicode.com';
$.ajax(baseApiUrl + '/posts/1')
  .then(function(post) {
    $.ajax(baseApiUrl + '/users/' + post.userId)
      .then(function(user) {
        console.log('got name: ' + user.name);
      }, function(error) {
        console.log('error when calling /users/', error)
      });
  }, function(error) {
    console.log('error when calling /posts/', error)
  });

【讨论】:

    【解决方案2】:

    简短回答:像往常一样,我正在尝试做一些这样的连锁店:

    ajaxCall1.then(
      response => ajaxCall2(response)
    ).then(
      response => ajaxCall3(response)
    )
    

    我试图避免使用when。像往常一样,我(也打赌你)有 1 个 ajax 调用(用于表单提交),有时有 2 个链接 ajax 调用,例如,如果我需要获取表的数据,首先查询总行数,如果计数大于0,再次调用数据。在这种情况下,我正在使用:

        function getGridData() {
          var count;
          callForRowsCount().then(
             (response) => {
                count = response;
                if(count > 0) {
                  return callForData();
                } else {
                  return [];
                }
             }
          ).then(response => {
             pub.fireEvent({
               type: 'grid-data',
               count: count,
               data: response
             })
          })
    }
    

    publisher 触发事件,我的所有组件都更新了。

    在极少数情况下,我需要使用when。但这总是糟糕的设计。如果我需要在主请求之前加载附加数据包,或者当后端不支持批量更新,并且我需要发送 ajax 调用包来更新许多数据库实体时,就会发生这种情况。像这样的:

    var whenArray = [];
    if(require1) {
      whenArray.push(ajaxCall1);
    }
    if(require2) {
      whenArray.push(ajaxCall2);
    }
    if(require3) {
      whenArray.push(ajaxCall3);
    }
    $.when.apply($, whenArray).then(() => loadMyData(arguments));
    

    【讨论】:

      猜你喜欢
      • 2018-04-28
      • 1970-01-01
      • 2019-04-25
      • 2013-07-17
      • 1970-01-01
      • 2019-03-23
      • 2016-03-27
      • 1970-01-01
      • 2014-09-02
      相关资源
      最近更新 更多