首页 > 解决方案 > 如何在我的 jQuery 'each' 函数及其所有包含的 AJAX 调用之后触发我的函数?

问题描述

纽布在这里。我尝试了在 SO 和其他地方找到的多种解决方案。这我试图遵循的,以确保在进行所有 ajax 调用之前我的函数不会触发。出于某种原因,当我的 updateValues 函数触发时,控制台日志不会返回在我的“第一个”jQuery 每个函数中更新的数据。但是,如果我在第一次之后直接再次单击“保存按钮”,控制台日志会显示正确的数据,因为每个函数都会更新。我已经按照我找到的所有示例进行操作,但我很困惑。提前致谢!

$("body").on("click",".saveButton",function(){
    var first = $(".item");
    var i = 0; 
    first.each(function(){
        var $this = $(this);
        var thisID = $this.find(".itemID").html();
        var itemProperties = {'Status': 'New'};
        updateListItem(_spPageContextInfo.webAbsoluteUrl,'TestList',thisID,itemProperties,printInfo,logError);
        i += 1;
        if(i == first.length) {
            updateValues();
        }
        function printInfo()
        {
            console.log('UPDATED!');
        }
        function logError(error){
            alert("An error occurred.");
            console.log(JSON.stringify(error));
        }
    });
    function printInfo(){
        console.log('UPDATED!');
    }
    function logError(error){
        alert("An error occurred.");
        console.log(JSON.stringify(error));
    }
});

function updateValues(){
    var url = _spPageContextInfo.siteServerRelativeUrl+
        "/_api/lists/getbytitle('TestList')/items?";
    $.ajax({
        url: url,
        method: 'GET',
        beforeSend: function (XMLHttpRequest){
            XMLHttpRequest.setRequestHeader('Accept', 'application/json; odata=verbose');
            },
        success: function( data ) {
            console.log(data);
            $(".itemTwo").each(function(){
                var $this =  $(this);
            });
        }   
    }); 
}

function updateListItem(webUrl,listTitle,listItemId,itemProperties,success,failure){
     var listItemUri =  webUrl + "/_api/web/lists/getbytitle('" + listTitle + "')/items(" + listItemId + ")";
     var itemPayload = {
       '__metadata': {'type': "SP.Data.IntakeTESTListItem"}
     };
     for(var prop in itemProperties){
           itemPayload[prop] = itemProperties[prop];
     }
     updateJson(listItemUri,itemPayload,success,failure);
}

function updateJson(endpointUri,payload, success, error){
    $.ajax({       
       url: endpointUri,   
       type: "POST",   
       data: JSON.stringify(payload),
       contentType: "application/json;odata=verbose",
       headers: { 
          "Accept": "application/json;odata=verbose",
          "X-RequestDigest" : $("#__REQUESTDIGEST").val(),
          "X-HTTP-Method": "MERGE",
           "If-Match": "*"
       },   
       success: success,
       error: error
    });
}

标签: javascriptjquery

解决方案


tl;dr:您运行两个 ajax 调用,在这种情况下,GET响应比POST请求更快(可能之前的数据更少,或其他情况),因此您将在第一时间获得过时的数据。

我希望更长的时间更具描述性:

你有两个 ajax 调用。第一个POST是一些东西,第二个是请求中GET改变的东西。POST不幸的是,它们同时运行。当 js 引擎看到一些 ajax 调用时,它不会等待响应执行下一行,而是继续进行。jquery ajax 调用中的回调会在将来响应返回时被调用。

您可能希望GET在收到POST' 成功(或错误,我不知道用例)后运行。所以你想在响应updateValues后调用函数。UpdateJson使用回调,它很混乱 - 您必须在成功时传递updateValueupdateJson调用它。如果可以,请使用 promises - nativefetch API或类似axios. 它更清洁和可读。

提示:您可能不想为每个项目运行 ajax 调用。而是只运行一个POST包含所有数据(如果你有这样的端点)和一个GET然后for-each循环更新前端。

更新我不知道 jquery,但我刚刚在链接问题中看到 jquery 有when / then方法。使用它们,您可以在其他一些完成后调用下一个 ajax 请求。


推荐阅读