Больше JQuery / Ajax и когда / сделали / обещают путаницу

Еще раз я борюсь с вызовами ajax - на этот раз вокруг какой-то проблемы с цепочкой. В общем, вот что мне нужно сделать: я перебираю некоторый массив, и для каждого элемента в массиве мне нужно сделать следующее: Выдать вызов Ajax, и, при успешном завершении, мне нужно выпустить три других вызова, которые должны быть с цепью, поэтому они запускаются последовательно.

Когда все элементы массива имеют как главный вызов, так и три подкоманды с цепочкой, я должен быть в состоянии сделать некоторые действия.

Моя проблема заключается в том, что программа не дожидается завершения трех подколей. В приведенном ниже коде это видно из инструкции «Готово» в журнале, которая появляется до завершения подколов.

Я создал JSFiddle здесь: https://jsfiddle.net/LeifFrederiksen/td534phz/1/

Примечание. У меня есть две разные функции для функции addAttachments (addAttachments и addAttachmentsAlternative) - ни одна из них не работает так, как должна.

var items = ["A","B"];

save();

function doneSaving() {
  log("<H1>Done</H1>");
}

function save() {
    // Save all items, and do something when all is done...
  log("<H1>Save initiated</H1>");

  var returnValue = saveItems();
  $.when(returnValue).done(function() {
    doneSaving();
  })
}

function saveItems() {
    // Loop through all items and save each of them...
  var requests = Array();

  // Build array of requests to wait for...
  for (item of items) {
    requests.push(saveOneItem(item));
  }


   var returnValue = $.when.apply($, requests).done(function() {
        log("All requests completed");
   })

  return returnValue;
}

function saveOneItem(item) {
  // Save one item...
  return addListItem(item,addListItemSuccess,addListItemFailure);
}

function addListItem(item, successFunction, failureFunction) {
   // The actual ajax that handles saving to database (actually Sharepoint via REST)...

   log("addListItem on: " + item);

    var returnValue = 
     $.ajax({
        url: "/echo/json/",

        data: {html: item,
               delay: 1},

            }).done(function (data) {
            if (successFunction != undefined) {
                returnValue = successFunction(item, data); // Returns the newly created list item information
                return returnValue;
            }
        }).fail(function (data) {
            return failureFunction(item, data);
        });

    return returnValue;
}

function addListItemSuccess(item,data) {
    log("addListItem succces - in succes function for " + item);

    returnValue = addAttachmentsAlternative(item,data);
    return returnValue;
}

function addAttachments(item,data) {
  var attachment1Deferred = addListItem(item + "-attachment 1",addAttachmentSuccess,addAttachmentFailure);

  var attachment2Deferred = attachment1Deferred.then(
            function() {
               return addListItem(item + "-attachment 2",addAttachmentSuccess,addAttachmentFailure);
            });
     var attachment3Deferred = attachment2Deferred.then(
             function() {
               return addListItem(item + "-attachment 3",addAttachmentSuccess,addAttachmentFailure);
             });

    attachment3Deferred.done(
           function() {
             log("Completed upload of all attachments for " + item);
            })
    return attachment3Deferred;                                   
}

function addAttachmentsAlternative(item,data) {
 return addListItem(item + "-attachment 1",addAttachmentSuccess,addAttachmentFailure)
                        .done(function(data) {
                            return addListItem(item + "-attachment 2",addAttachmentSuccess,addAttachmentFailure)
            }).done(function(data) {
                            return addListItem(item + "-attachment 3",addAttachmentSuccess,addAttachmentFailure)
            }).done(function(data) {
                log("Completed alternative upload of all attachments for " + item);
            });
}    
function addAttachmentSuccess(item,data) {
    log("addAttachment succces - in succes function for " + item);
    var deferred = $.Deferred();
    deferred.resolve();
    return deferred;
}

function addListItemFailure(item,data) {
    console.log("addListItem failed - calling failure function for " + item);
    $("#console").append("<P>addListItem failed - in failure function for " + item);
}

function addAttachmentFailure(item,data) {
    console.log("addListItem failed - calling failure function for " + item);
    $("#console").append("<P>addListItem failed - in failure function for " + item);
}

function log(message) {
    console.log(message);
    $("#console").append("<P>" + message);

}

Я надеюсь получить некоторые общие шаблоны, которые я могу использовать в разных случаях.

Я получил вдохновение от этой замечательной статьи, но не могу заставить ее работать по моему сценарию: https://medium.com/coding-design/writing-better-ajax-8ee4a7fb95f#.tu0sruz5k

Любые идеи и материалы более чем приветствуются.

С уважением Лейф

javascript,jquery,ajax,

0

Ответов: 1


0 принят

В приведенном примере есть несколько проблем:

  • для цепочки задач создания элементов списка и добавления вложений .thenвместо использования .done. При обратном вызове, .doneкоторый печатает, All requests completedон запускается после того, как отложенный (первый вызов addListItemфункции ajax ) становится разрешенным.
  • некоторые функции, как и addListItemвсе еще, используют синтаксис функции обратного вызова, я бы предложил преобразовать их в обещания
  • поскольку все отложенные становятся решаемыми в saveItemsфункции, нет необходимости использовать jQuery.when()в saveфункции

Модифицированная демоверсия

JavaScript, JQuery, AJAX,
Похожие вопросы