在Sequence中执行Ajax请求

时间:2016-01-01 10:33:24

标签: javascript

感谢您查看我的问题。我希望你能帮助我朝着正确的方向前进。

问题: 用户发送公司名称列表,服务器发回相应的徽标。 限制是徽标需要从左到右,然后从上到下放置。 订单不应该改变。

方法跟随: 我们正在使用一排公司名称 - 喜欢: [[公司_ 第1行],[公司_ 第2行],[公司_ 第3行]]

每个[Companies_Row]都有['福特','宝马','奥迪'等价值观 [Car Array Looks Like This

我们希望徽标按顺序显示,但是目前我们是以随机顺序获取它们。

我们正在考虑的解决方案是迭代数组并使用Promises。 但是,自从过去两天以来,我们一直在努力实现这一目标。请帮我们解决。

代码段:

    // arrayOfCompanyNames - contains an Array of [Array of Company Names] appearing in a row. Please Refer Screenshot.

   // Function where we are traversing the company Name and making call
    function getCompanyLogos(arrayOfCompanyNames) {
      var promise = new Promise(function(resolve, reject) {
        resolve(1);
      });
      promise.then(function(){
        arrayOfCompanyNames.forEach(function(item) {
          item.forEach(function(value, index) {
            if(index == item.length - 1){
              // When a row is complete then move to the next row.
              promise = promise.then(LogoFetchPromis(value, true));
            } else {
              promise = promise.then(LogoFetchPromis(value));
            }
          });
        });
      });
    }



function LogoFetchPromis(carName, wrapNow){
    return new Promise(function(resolve, reject) {
      $.ajax({
          url: "/getLogo/" + carName,
          dataType: 'text'
        })
        .done(function(response) {
          resolve(response);
     // logos is the section where logos should appear
          $('.logos').append(response);
          if (wrapNow)
            $('.logos').append('<br>');
        })
        .fail(function(response) {
          reject(Error(response));
        });
    });
}

请帮助我们找到相同的解决方案。

1 个答案:

答案 0 :(得分:1)

保持简单。一种解决方案是首先通过构建一组promises来获取所有图像,再现arrayOfCompanyNames的结构,然后使用Promise.all()来保持promises结果的顺序。然后,您可以遍历结果数组并显示徽标(根据需要添加错误管理)。

// arrayOfCompanyNames - contains an Array of [Array of Company Names] appearing in a row. Please Refer Screenshot.
var arrayOfCompanyNames;

// Function where we are traversing the company Name and making call
function getCompanyLogos(arrayOfCompanyNames) {
    // build an array of promises mirroring arrayOfCompanyNames
    var promises = [];
    arrayOfCompanyNames.forEach(function (subArray) {
        var subPromises = [];
        subArray.forEach(function (carName) {
            // $.ajax is a promise so you use it directly
            subPromises.push($.ajax({
                url: '/getLogo/' + carName,
                dataType: 'text'
            }));
        });
        promises.push(Promise.all(subPromises));
    });

    // show everything, results is nicely formatted so you know when to <br>
    return Promise.all(promises).then(function done(results) {
        // results look like [[row1], [row2], [row3]]
        results.forEach(function (row) {
            row.forEach(function (carLogo) {
                $('.logos').append(carLogo);
            });
            $('.logos').append('<br>');
        });
    })
}

Promise.all()解决方案会引入延迟,当他们全部获取时,徽标会立即显示。它们将同时全部下载,因此如果您不是您要求的服务器(请注意几乎100个并发请求),请务必小心。

另一种方式是你开始建立一个承诺链。

// arrayOfCompanyNames - contains an Array of [Array of Company Names] appearing in a row. Please Refer Screenshot.
var arrayOfCompanyNames;

// Function where we are traversing the company Name and making call
function getCompanyLogos(arrayOfCompanyNames) {
    // this is enough to create a 'base' resolved promise
    var promise = Promise.resolve();

    arrayOfCompanyNames.forEach(function (item) {
        item.forEach(function (value, index) {
            if (index == item.length - 1) {
                // When a row is complete then move to the next row.
                promise = promise.then(LogoFetchPromis.bind(null, value, true));
            } else {
                promise = promise.then(LogoFetchPromis.bind(null, value));
            }
        });
    });

    return promise;
}

function LogoFetchPromis(carName, wrapNow) {
    // don't create a new Promise here, $.ajax is already a promise
    return $.ajax({
        url: "/getLogo/" + carName,
        dataType: 'text'
    }).done(function (response) {
        // logos is the section where logos should appear
        $('.logos').append(response);
        if (wrapNow)
            $('.logos').append('<br>');
    }).fail(function (response) {
        // manage error here is needed
    });
}

我评论了这些变化,但最重要的是promise.then(LogoFetchPromis(value));。您直接致电LogoFetchPromis(),这就是您的徽标随机显示的原因,所有$ .ajax实际上是一次性完成的。在固定代码(promise.then(LogoFetchPromis.bind(null, value))中,bind()返回一个在promise被解析之前不会执行的Function,因此将一次调用LogoFetchPromis(),并且您的徽标应显示在顺序。