首页 > 解决方案 > 仅当列表中添加了 ajax 请求时才调用 ajax 请求

问题描述

设置


我有一个表单,它使用一系列复选框来确定页面上选择的数字:

这里复选框的数学是正确的。 应该是 4

它所做的是在选中时调用一个控制器,该控制器将保存选择并根据其当前数据返回新的检查金额。

代码看起来像这样


$('#myId').('click', '.selectorClass input', function() {
    const inputCheckBox = this;
    inputCheckBox.disabled = true;
    $(inputCheckBox).addClass('disabled-checkbox')

    $.ajax({ 
       method: "POST",
       url: "@(Url.Action<MyController>(c => c.MyEndPoint(Model.ItemId, null)))",
       data: {
          "boxWasChecked": inputCheckBox.checked
       }
    }).done(function (data) {
       UpdateFields(inputCheckBox, data); //this would update the column footer and 'Total Quantity' field below
    }).fail(function (data) {
       // error check and handle here
    }).always(function(data) {
       inputCheckBox.disabled = false;
       $(inputCheckBox).removeClass('disabled-checkbox')
    });
});

这在一次选择一个时非常有效,甚至在选择多个时通常也有效。


问题


当用户非常快速地选择它们时,问题就出现了,然后有时最后一个完成的请求不是最后一个进入/从控制器端的数据库中获取数据的请求,因此它带回了错误的总数。

请参见下图,其中数学应该是 11(记住它是添加每个框的值而不是选中的框数)但报告的是 6。
如果我要选择最后一个复选框,它会正确报告 12,因为它有呼叫的所有正确数据。

复选框的数学不正确。 应该是 11


我被卡住的部分


我想我需要以某种方式制作一个 ajax 调用列表,然后只有在它之后添加一个请求或者它前面的所有其他请求都已完成时才取消请求。我不知道如何使用 ajax 调用来做到这一点。

我玩弄了promises/Fetch API并试图让它工作,但可以得到承诺添加到Promise.all[myListOfAjaxCalls].

我正在努力的代码摘要

var listOfPromiseCalls = []

$('#myId').('click', '.selectorClass input', function() {
     // my checkbox is clicked
    listOfPromiseCalls.push(myAjaxCall/myPromise)
    // Psudeo code   
    // begin request if it is the only one in the list
    // else
        // kick off other requests that are in existing list infront of it
    // if other requests finish before another input is clicked, begin this request
});

标签: javascriptjqueryajaxasp.net-mvcfetch

解决方案


我认为通过创建包含所有请求的列表,您走在正确的道路上,但是由于您使用 jQuery 进行异步调用,因此您应该使用$.when 运算符等待,直到所有请求都完成。Promise.all不会工作,因为$.ajax它没有实现与 a 相同的接口new Promise(),因此您需要使用 jQuery 运算符来处理它。

如上所述,您可以使用包含所有异步调用的列表,然后执行以下操作:

$.when(...listOfPromiseCalls)
  .done((...allResponses) => {
    // do something 
  })
  .catch(errors => {
    // handle errors
  });

请注意,我正在使用es6 中的扩展运算符将所有请求传播到响应列表中,when并将所有响应聚合到响应列表中。

关于传播语法:https ://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax

如果你不会使用es6语法,我建议你学习和使用applyjs函数的方法,它给你同样的结果。


推荐阅读