更多的JQuery/Ajax和when/done/promise混淆

More JQuery/Ajax and when/done/promise confusion

本文关键字:when done promise 混淆 Ajax JQuery      更新时间:2023-09-26

我再次与ajax调用作斗争-这次是围绕一些链接问题。总的来说,这是我需要完成的:我循环遍历某个数组,对于数组中的每一项,我需要做以下操作:发出一个Ajax调用,成功后,我需要发出另外三个调用,它们必须被链接起来,这样它们才能按顺序运行。

当数组中的所有项都完成了它们的主调用和三个链式子调用时,我必须能够执行一些操作。

我的问题是,程序没有等待三个链式子调用完成。在下面的代码中,可以看到日志中的"Done"语句在子调用完成之前出现。

我在这里创建了一个JSFiddle: https://jsfiddle.net/LeifFrederiksen/td534phz/1/

注意:我有两个不同的addAttachments函数(addAttachments和addattachmentsalalternative) -它们都不像它们应该的那样工作。

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

欢迎大家提出意见和建议。

的问候列夫

提供的示例有几个问题:

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

修改演示/strong>