如何确定 jquery ajax 调用何时完成?

我有一个国家/地区下拉列表,并有一个 jquery ajax 调用,该调用使用国家/地区名称填充下拉列表。问题是我需要知道呼叫何时完成,然后才能确定选择了哪个国家/地区。也就是说,我在使用 ajax 调用的函数之后调用的任何函数都被过早调用(在下拉列表填充之前),因此以下函数将崩溃。我也不想使用 async=false (因为这会导致更多问题并且是不好的做法)。实现这一目标的正确方法是什么?


这是一个通用的 ajax 函数,用于检索数据并使用参数 id 填充特定类型的选择下拉列表 (ddl):


   function RetrieveDD(ddl, ddtype, id) {

        var servicename;

        switch (ddtype) {

            case 'country':

                servicename = "LoadCountries";

                break;

            case 'state':

                servicename = "LoadStateProvinces";

                break;

            case 'city':

                servicename = "LoadCityLocalities";

                break;

            default:

                servicename = "";

        }

                error: function (err) {

                    console.log('Error (RetrieveDD): ' + JSON.stringify(err, null, 2));

                }

            });

        };

    };

我有一个执行此操作的测试按钮,并希望获取所选选项的值(它将调用填充状态,获取第一个选定状态的值并再次调用以填充城市)。问题很明显:我不能说在不知道前一个下拉列表的选定值的情况下填充下一个下拉列表(所以我必须有办法等待下拉列表填充第一个)。


        $('#btnTest').click(function () {

           RetrieveDD($("#ddlCountries"), "country", 0);


            var cid = $("#ddlCountries").val();  //this is still undefined because ajax call above not completed 

            alert("cid = " + cid);    //normally another call would be made here to populate the states

        });

单击该按钮时,您会立即看到一个警告框弹出窗口(没有 cid 值),并且直到您单击警告对话框中的 [确定] 按钮后,国家下拉列表才会填充。基本上,它的顺序是错误的。


如果我将async:false添加到 ajax 例程中,您将看到显示正确 cid 的警报,但是,正如人们发布的那样,您永远不应使用async:false。我希望避免这种情况,但不确定如何正确执行此操作。(如果有人想知道,我正在从旧的 dotnet webforms 网站中删除所有 MSAjaxToolkit 废话,并用 jQuery ajax 替换——它更快、更小、更容易修复。)


************** 回应为什么我认为这不是重复的 ********* 需要添加对旧 IE 支持的要求(Windows 7 附带、8、8.1 和一些服务器版本)。IE 不支持箭头函数或 promise(或 2015 年之后的大多数 ECMA 方法),因此很多推荐的答案虽然很好,但没有包含此类代码。我会尝试解决这个问题并在这里发布。


梵蒂冈之花
浏览 214回答 3
3回答

幕布斯7119047

类似于 John M 的回答,但用法不同。返回$.ajax承诺并使用.done()if (servicename!="")     return $.ajax({...// else return null$('#btnTest').click(function () {    var ajax = RetrieveDD($("#ddlCountries"), "country", 0);    if (ajax) {          ajax.done(function(data) {              console.log('done');        });    }});

Helenr

JQuery.ajax() 实现了 Promise 接口,因此您可以获取 ajax 调用返回的 Promise 对象并将其传递回您的调用函数。那可以在ajax调用完成后使用Promise.then()来调用代码,我认为这比使用回调更简洁。&nbsp; &nbsp;function RetrieveDD(ddl, ddtype, id) {&nbsp; &nbsp; var servicename;&nbsp; &nbsp; var promise;&nbsp; &nbsp; switch (ddtype) {&nbsp; &nbsp; &nbsp; &nbsp; case 'country':&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; servicename = "LoadCountries";&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;&nbsp; &nbsp; &nbsp; &nbsp; case 'state':&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; servicename = "LoadStateProvinces";&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;&nbsp; &nbsp; &nbsp; &nbsp; case 'city':&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; servicename = "LoadCityLocalities";&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;&nbsp; &nbsp; &nbsp; &nbsp; default:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; servicename = "";&nbsp; &nbsp; }&nbsp; &nbsp; if (servicename != "") {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;promise = $.ajax({&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; url: 'DDService.asmx/' + servicename,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dataType: 'json',&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; method: 'post',&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; data: { ID: id },&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; success: function (data) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ddl.empty();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $.each(data, function (index) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ddl.append($("<option" + (index == 0 ? " selected" : "") + "></option>").val(this['V']).html(this['T']));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.log('update list');&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; });&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; },&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; error: function (err) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.log('Error (RetrieveDD): ' + JSON.stringify(err, null, 2));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; });&nbsp; &nbsp; };&nbsp; &nbsp; return promise;};$('#btnTest').click(function () {&nbsp; &nbsp; var promise = RetrieveDD($("#ddlCountries"), "country", 0);&nbsp; &nbsp; if (promise) {&nbsp; &nbsp; &nbsp; &nbsp; promise.then(function(value) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var cid = $("#ddlCountries").val();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.log('done');&nbsp; &nbsp; &nbsp; &nbsp; });&nbsp; &nbsp; }});

DIEA

在您的函数中使用回调:function RetrieveDD(ddl, ddtype, id, callback = false) {&nbsp; &nbsp; // ...&nbsp; &nbsp; if (servicename != "") {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;$.ajax({&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; url: 'DDService.asmx/' + servicename,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dataType: 'json',&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; method: 'post',&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; data: { ID: id },&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; success: function (data) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // ...&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(typeof callback === 'function'){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; callback(data);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; },&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; error: function (err) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // ...&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(typeof callback === 'function'){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; callback(err);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; });&nbsp; &nbsp; };};RetrieveDD($("#ddlCountries"), "country", 0, (data_or_error)=>{&nbsp; &nbsp; var cid = $("#ddlCountries").val();});
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript