更多JQuery / Ajax以及何时/完成/承诺混淆

时间:2016-10-14 12:26:16

标签: javascript jquery ajax

我再一次与ajax调用斗争 - 这次围绕着一些链接问题。总的来说,这就是我需要完成的事情: 我遍历一些数组,对于数组中的每个项目,我需要执行以下操作: 发出一个Ajax调用,一旦成功,我需要发出三个其他调用,这些调用必须是链接的,所以它们按顺序运行。

当数组中的所有项都有主调用和三个链式子调完成时,我必须能够做一些动作。

我的问题是,该程序不会等待三个链式子语句完成。在下面的代码中,这可以通过" Done"在子语句完成之前,日志中的语句会出现。

我在这里创建了一个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

任何想法和意见都非常受欢迎。

此致 雷夫

1 个答案:

答案 0 :(得分:0)

提供的示例有几个问题:

  • 链接创建列表项和添加附件使用的任务 .then代替.done。使用.done回调打印All requests completed,一旦延迟(addListItem函数中的第一个ajax调用)被解析,它就会被触发。
  • addListItem这样的函数仍然使用回调函数语法,我建议将它们转换为promises
  • 由于所有推迟都在saveItems函数中得到解决,因此无需在jQuery.when()函数中使用save

Modified demo