【问题标题】:How can I return a value from a function that uses a jQuery ajax call?如何从使用 jQuery ajax 调用的函数返回值?
【发布时间】:2012-01-11 17:21:32
【问题描述】:

我有以下 Javascript 函数调用 Asp.Net WebMethod,如果用户名已经存在则返回 true,如果不存在则返回 false。 以下将在警告框中为我提供正确答案,但如果我更改 alert(result.d) 返回 result.d 函数的结果总是未定义的。 如何获取包含 Ajax 调用的函数以根据 WebMethod 的响应返回值?

function doesEnteredUserExist() {
        var valFromUsernameBox = $("#txtUserName").val();
        var jsonObj = '{username: "' + valFromUsernameBox + '"}'; 

        $.ajax({
        type: 'POST',
        contentType: 'application/json; charset=utf-8',
        data: jsonObj,
        dataType: 'json',
        async: false,
        url: 'AddNewUser.aspx/IsUserNameValid',
        success: function (result) {
            alert(result.d);
        },
        error: function (err) {
            alert(err);
        }
    });
}

【问题讨论】:

    标签: asp.net jquery


    【解决方案1】:

    需要注意的是ajax 函数是非阻塞。您指定两个回调函数,一个用于success,一个用于error,当底层请求完成时将执行其中一个函数。

    您的doesEnteredUserExist 不会等待ajax 调用完成,因此函数的返回值为undefined。

    根据您的调用结果继续执行的正确方法是将您的功能分解为一个单独的函数,然后从您的 success 函数中调用它。

    【讨论】:

      【解决方案2】:

      Ajax 是异步的,因此一旦函数“doesEnteredUserExist”返回,ajax 调用尚未完成。然后稍后在成功回调中,您将获得该值。从那里您应该继续使用您的代码并向用户显示信息。

      【讨论】:

      • 即使我设置了 async: false 设置了它?
      • 好的,然后执行:return $.ajax({ /* ... */ });
      【解决方案3】:

      将result.d 的值存储在一个变量中,然后根据需要使用它。

      改变这个:

      success: function (result) {
              alert(result.d);
          },
      

      到这里:

      success: function (result) {
              var resultString = result.d;
          },
      

      现在,当您需要result.d 时,只需使用变量resultString。基本上,ajax 调用是唯一可以调用您想要为其返回值的函数的方法,因此您需要在调用该函数时存储该值。

      【讨论】:

        【解决方案4】:

        也许给它一个狂欢 函数onSucess(数据){ 警报(数据.d); }

        function doesEnteredUserExist() {
            var valFromUsernameBox = $("#txtUserName").val();
            var jsonObj = '{username: "' + valFromUsernameBox + '"}'; 
        
            $.ajax({
            type: 'POST',
            contentType: 'application/json; charset=utf-8',
            data: jsonObj,
            dataType: 'json',
            async: false,
            url: 'AddNewUser.aspx/IsUserNameValid',
            success: onSucess,
            error: function (err) {
                alert(err);
            }
        });   
        }
        

        【讨论】:

          【解决方案5】:

          我猜您正在尝试设置超出调用范围的 result.d,这就是为什么警报 (result.d) 在其范围内起作用的原因。

          我可能弄错了,你可以使用一个全局变量(不推荐),在 ajax 返回中设置它,然后你可以从你的函数中读取。

          在我以几种方式阅读问题时,可能需要更多信息或澄清您试图实现的目标。

          我通常这样做(没有测试过):

          function ajaxLoad(callback)
          $.ajax({
                  type: 'POST',
                  async: true,
                  url: 'url.aspx',
                  data: d,
                  cache: false,
                  contentType: 'application/json',
                  dataType: 'json',
                  error: function (xmlHttpRequest, textStatus, errorThrown) {
              //error stuff
                  },
                  success: function (data) {
                     if (typeof callback == 'function') { [callback(data)]; }
                  }
              });
          
          }
          
          function callback(data)
          {
              alert(data);
          }
          

          调用函数使用 ajaxLoad('回调');

          类似的东西!

          【讨论】:

            【解决方案6】:

            在您的 success 回调函数中,如果您 return 某个值,它不会为其父函数设置 return 值。在这种情况下,父函数是$.ajax,它总是返回一个 jqXHR 延迟对象。

            如果您使用的是 jQuery 1.5 或更高版本,则可以使用延迟。这个想法是保存从 AJAX 请求返回的 jqXHR 对象,并等待它完成,然后再返回它的值:

            var jqXHR = $.ajax({...});
            
            $.when(jqXHR).then(function (result) {
                return result.d
            });
            

            $.when() 的文档:http://api.jquery.com/deferred.when

            这样做的一个例子是从你的函数中返回 jqXHR 对象,然后等待 AJAX 请求在函数外解析:

            function doesEnteredUserExist() {
                return $.ajax({...});
            }
            $.when(doesEnteredUserExist).then(function (result) {
                //you can access result.d here
            });
            

            【讨论】:

              【解决方案7】:

              正如@timing 所提到的,当从函数返回值时,ajax 调用还没有完成,所以每次你得到未定义的。

              这不是问题的解决方案,但是您可以尝试显示它的另一种方法是代替返回值,只需使用返回的文本更新某些元素(如 div)的 innerHTML。以下是我的意思:

              function doesEnteredUserExist() {
                  var valFromUsernameBox = $("#txtUserName").val();
                  var jsonObj = '{username: "' + valFromUsernameBox + '"}'; 
              
                  $.ajax({
                  type: 'POST',
                  contentType: 'application/json; charset=utf-8',
                  data: jsonObj,
                  dataType: 'json',
                  async: false,
                  url: 'AddNewUser.aspx/IsUserNameValid',
                  success: function (result) {
                      //alert(result.d); 
                     if(result.d==true){  //Just a check for the value whether true or 1 etc..
                     $("#notifications").html('Username Already Exists'); // Have a div where you can display the message (named it notifications here) , update the notifications div text to notify the user
                     }else{
                        $("#notifications").html('Username is Available');
                     }
                  },
                  error: function (err) {
                      alert(err);
                  }
              });
              }
              

              【讨论】:

                【解决方案8】:

                这似乎是$.Deferred 对象使用的一个很好的例子

                这个想法很简单(真的,我承诺,:) 看到代码上的步骤)

                1. 创建一个新的延迟对象
                2. 进行 ajax 调用。如果结果为假,您将拒绝延迟,否则您将解决它(您也可以在 errorajax 回调中拒绝它)
                3. 兑现承诺
                4. 使用.when() helper 检查承诺的状态。

                我创建了一个在响应中随机返回真或假的小提琴

                function checkUserExist() {
                    var dfd = $.Deferred();  /* step 1 */
                
                    $.ajax({
                        url: "/echo/json/",
                        data: {
                            "json": JSON.stringify({d: (Math.random() < 0.5) })
                        },
                        type: "POST",
                        success: function (data) {
                            console.log("result (inside ajax callback) ", data.d);
                            if (!data.d) { dfd.reject() } else { dfd.resolve(); } /* step 2 */
                        },
                        error : ...
                    });
                
                    /* step 3 */         
                    return dfd.promise();
                
                }
                
                $.when(checkUserExist())  /* step 4 */
                    .fail(function() { console.log("user don't exist (inside fail)"); })
                    .done(function() { console.log("user already exist (inside done)"); })
                

                小提琴网址:http://jsfiddle.net/Gh9cN/

                (注意:我已经更改了一些内部细节,以便在 jsfiddle 上运行)

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 2013-10-04
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2019-11-20
                  • 1970-01-01
                  相关资源
                  最近更新 更多