Спасибо за просмотр моего вопроса. Надеюсь, вы поможете мне двигаться в правильном направлении.

Проблема: Пользователь отправляет список названий компании, а сервер возвращает соответствующий логотип. Ограничение состоит в том, что логотип нужно размещать слева направо, а затем сверху вниз. Порядок не должен меняться.

Применяемый подход: Мы используем массив названий компаний, отображаемых по строкам - Нравится: [[Компании_Строка1], [Компании_Строка2], [Компании_Строка3]]

Каждый [Companies_Row] имеет такие значения, как [«Ford», «BMW», «Audi»]. [Car Array Looks Like This

Мы ожидаем, что логотипы появятся по порядку, однако в настоящее время мы получаем их в случайном порядке.


Решение, которое мы думаем, состоит в том, чтобы перебирать массивы и использовать промисы. Однако последние два дня мы изо всех сил пытаемся реализовать это. Пожалуйста, помогите нам решить эту же проблему.

Фрагменты кода:

    // 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('
'); }) .fail(function(response) { reject(Error(response)); }); }); }

Пожалуйста, помогите нам найти разрешение для того же.

vedvrat13

Ответов: 1

Ответы (1)

Будь проще. Одно из решений - сначала получить все ваши изображения, построив массив обещаний, воспроизводящий структуру arrayOfCompanyNames, а затем использовать Promise.all (), чтобы сохранить порядок результатов обещаний. А затем вы можете перебрать массив результатов и показать логотипы (при необходимости добавьте управление ошибками).

// 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 
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('
'); }); }) }

Решение 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('
'); }).fail(function (response) { // manage error here is needed }); }

Я прокомментировал изменения, но наиболее важным является promise.then (LogoFetchPromis (value));. Вы вызываете LogoFetchPromis () напрямую, поэтому ваши логотипы отображаются случайным образом, все $ .ajax фактически выполняются одновременно. В фиксированном коде (promis.then (LogoFetchPromis.bind (null, value)) bind () возвращает функцию, которая не выполняется до тех пор, пока не будет разрешено обещание, поэтому LogoFetchPromis () будут вызываться по очереди, и ваши логотипы должны отображаться по порядку.

2022 WebDevInsider