Javascript 我可以做些什么来避免同步AJAX请求

Javascript 我可以做些什么来避免同步AJAX请求,javascript,jquery,ajax,Javascript,Jquery,Ajax,我有这个数组 var testFlows = ["test1","test2","test3","test4","test5"]; 我试图一个接一个地获取输入并生成一些html(生成的html其实并不重要) 重要的是,我希望按照testFlows数组的顺序查看这些html面板。我的代码完全是随机的。如果我刷新页面,它们位于不同的位置 一种解决方案是制作一个同步ajax,但它已经过时,而且很糟糕,所以我还能做什么呢 代码: var testFlows=[“test1”、“test2”、“test

我有这个数组

var testFlows = ["test1","test2","test3","test4","test5"];
我试图一个接一个地获取输入并生成一些html(生成的html其实并不重要)

重要的是,我希望按照testFlows数组的顺序查看这些html面板。我的代码完全是随机的。如果我刷新页面,它们位于不同的位置

一种解决方案是制作一个同步ajax,但它已经过时,而且很糟糕,所以我还能做什么呢

代码:

var testFlows=[“test1”、“test2”、“test3”、“test4”、“test5”];
$.each(测试流,函数(索引,测试流){
//获取输入
$.ajax({
url:“/flow/getInputs”,
键入:“post”,
数据:{testCaseName:testFlow.testCase.name},
成功:函数(inputNames){
testCaseAccordion='';
testCaseAccordion+='';
$('#accordion')。追加(testcaseacordion);
if(testFlow.params!==null){
var inputs=testFlow.params.split(',');
对于(变量i=0;i”+inputNames[i]+”:“+inputs[i]+”
”); } } 否则{ $(“#面板主体-”+testFlow.testCase.name+index).append(“此测试用例没有任何输入”); } } }); });
jQuery
ajax
返回一个承诺,因此您可以将所有承诺保存到一个数组中,例如:

var testFlows = ["test1", "test2", "test3", "test4", "test5"];

var testFlowsPromises = $.map(testFlows, function(testFlow, index) {
  //get the inputs
  return $.ajax({
    url: '/flow/getInputs',
    type: 'post',
    data: {testCaseName: testFlow.testCase.name}
  }).then(function(inputNames) {
    return {
      inputNames: inputNames,
      testFlow: testFlow
    };
  });
});
然后,等待所有操作完成:

$.when.apply($, testFlowsPromises).done(function() {
  $.each(arguments, function(index, data) {
    // do stuff with index, data.inputNames, data.testFlow
  });
});
现在,您将拥有一个顺序相同的ajax数据数组

演示


您可以使用承诺,例如,在您的情况下:

var testFlows = ["test1","test2","test3","test4","test5"];

function success(testFlowAndInputNames, index) {
    var testFlow = testFlowAndInputNames[0];
    var inputNames = testFlowAndInputNames[1];
    var testCaseAccordion = '<div class="panel panel-default"><div class="panel-heading"><h4 class="panel-title"><a class="collapseTitle" data-toggle="collapse" data-parent="#accordion" href="#collapse-' + testFlow.testCase.name + index + '">' + testFlow.testCase.name + '(' + testFlow.testCase.type.name + ') <span id="eyeIcon" class="fas fa-eye float-right"></span></a></h4></div>';
    testCaseAccordion += '<div id="collapse-' + testFlow.testCase.name + index + '" class="panel-collapse collapse"><div id="panel-body-' + testFlow.testCase.name + index + '" class="panel-body"></div></div>';
    $('#accordion').append(testCaseAccordion);
    if (testFlow.params !== null) {
        var inputs = testFlow.params.split(',');
        for (var i = 0; i < inputs.length; i++) {
            $('#panel-body-' + testFlow.testCase.name + index).append('<strong class="color-red">' + inputNames[i] + ': </strong>' + inputs[i] + '<br>');
        }
    }
    else {
        $('#panel-body-' + testFlow.testCase.name + index).append("This test case doesn't have any inputs");
    }
}


var arrayOfPromises = testFlows.map(function (testFlow) {
    return new Promise(function (resolve, reject) {
        $.ajax({
            url: '/flow/getInputs',
            type: 'post',
            data: {testCaseName: testFlow.testCase.name},
            success: resolve
        });
    })
    .then(function(inputNames) { 
        return [testFlow, inputNames];
    })
});

Promise.all(arrayOfPromises)
    .then(function(results) {
        results.forEach(success)
    });
var testFlows=[“test1”、“test2”、“test3”、“test4”、“test5”];
函数成功(testFlowAndInputNames,索引){
var testFlow=testFlow和输入名[0];
var inputNames=testflow和inputNames[1];
var testCaseAccordion='';
testCaseAccordion+='';
$('#accordion')。追加(testcaseacordion);
if(testFlow.params!==null){
var inputs=testFlow.params.split(',');
对于(变量i=0;i”+inputNames[i]+”:“+inputs[i]+”
”); } } 否则{ $(“#面板主体-”+testFlow.testCase.name+index).append(“此测试用例没有任何输入”); } } var arrayOfPromises=testFlows.map(函数(testFlow)){ 返回新承诺(功能(解决、拒绝){ $.ajax({ url:“/flow/getInputs”, 键入:“post”, 数据:{testCaseName:testFlow.testCase.name}, 成功:决心 }); }) .then(函数(输入名称){ 返回[testFlow,inputNames]; }) }); 承诺。全部(协议书) .然后(函数(结果){ 结果:forEach(成功) });
如果我使用
async:false创建代码,
它可以工作。但我不希望在一个请求中发送所有数据(即整个数组),然后根据需要在从请求返回的数组中循环。我建议使用承诺。真的没有必要在问题的各个部分随机加粗,阅读起来有点烦人。我同意Rory的观点。当只能发出一个HTTP请求时,不要发出10个HTTP请求,发送一个包含10个元素的数组。我应该将$.when.apply放在哪里?在所有事情之外?是的,在所有事情之外注意,这并不能保证响应的顺序,因为OP声明是一项要求,你能解释一下吗?所有请求完成后,响应的顺序与请求的顺序相同。在jsbin上添加了一个示例,响应顺序是有保证的。一点也不,promises API保证所有请求完成时的顺序。我明白你的意思,你倒过来说,承诺会以随机顺序完成,但承诺会按顺序完成。所以渲染是正确的。你完全正确。我的错误。很抱歉。不过,我还是建议OP提出一个请求。
var testFlows = ["test1","test2","test3","test4","test5"];

function success(testFlowAndInputNames, index) {
    var testFlow = testFlowAndInputNames[0];
    var inputNames = testFlowAndInputNames[1];
    var testCaseAccordion = '<div class="panel panel-default"><div class="panel-heading"><h4 class="panel-title"><a class="collapseTitle" data-toggle="collapse" data-parent="#accordion" href="#collapse-' + testFlow.testCase.name + index + '">' + testFlow.testCase.name + '(' + testFlow.testCase.type.name + ') <span id="eyeIcon" class="fas fa-eye float-right"></span></a></h4></div>';
    testCaseAccordion += '<div id="collapse-' + testFlow.testCase.name + index + '" class="panel-collapse collapse"><div id="panel-body-' + testFlow.testCase.name + index + '" class="panel-body"></div></div>';
    $('#accordion').append(testCaseAccordion);
    if (testFlow.params !== null) {
        var inputs = testFlow.params.split(',');
        for (var i = 0; i < inputs.length; i++) {
            $('#panel-body-' + testFlow.testCase.name + index).append('<strong class="color-red">' + inputNames[i] + ': </strong>' + inputs[i] + '<br>');
        }
    }
    else {
        $('#panel-body-' + testFlow.testCase.name + index).append("This test case doesn't have any inputs");
    }
}


var arrayOfPromises = testFlows.map(function (testFlow) {
    return new Promise(function (resolve, reject) {
        $.ajax({
            url: '/flow/getInputs',
            type: 'post',
            data: {testCaseName: testFlow.testCase.name},
            success: resolve
        });
    })
    .then(function(inputNames) { 
        return [testFlow, inputNames];
    })
});

Promise.all(arrayOfPromises)
    .then(function(results) {
        results.forEach(success)
    });