【问题标题】:jQuery - Wait for a function to return valuejQuery - 等待函数返回值
【发布时间】:2012-07-02 06:34:20
【问题描述】:

我有一个 jquery 函数,用于发送带有 ajax 请求的电子邮件;

function sendMail(from,to,subject,message){
    var datastr="from="+from+"&to="+to+"&subject="+subject+"&message="+message;
    $.ajax({
        type: "POST",
        url: "mail.php",
        data: datastr,
        cache: false,
        success: function(html){
            return true;
        },
        error: function(jqXHR,status,error){
            return false;
        }
    });
}

现在我想告诉用户邮件是否发送成功:

$("#feedback").html("Sending email...");
if(sendMail("from@email.com","to@email.com","MySubject","MyMessage"))
   $("#feedback").html("Email sent.");
else
   $("#feedback").html("Error sending email.");

当然 jQuery 在发送邮件之前会处理 if 条件,因此条件为 false :-( 我如何告诉 jQuery 等到 sendMail 完成并返回一些东西?

【问题讨论】:

    标签: jquery function return wait


    【解决方案1】:

    您的sendMail 函数不可能根据 AJAX 调用的结果返回真/假(除非您使用同步请求,这几乎总是一个糟糕的主意)。这正是浏览器中 JavaScript 的工作方式,出于充分的理由,我不会在这里讨论。

    相反,您必须告诉$.ajax 即使成功或失败该做什么。

    一种方法如下所示:

    $.ajax({
      // omitting arguments for clarity
      success: function(){
        $("#feedback").html("Email sent.");
      },
      error: function(){
        $("#feedback").html("Error sending email.");
      }
    });
    

    【讨论】:

      【解决方案2】:

      虽然给定的答案是有效的,但我会考虑将 sendmail 函数和 DOM 修改分开(即,将 $("#feedback").html... 排除在 success/error 回调之外)。您可以通过返回 ajax 调用的结果来做到这一点:

      function sendMail(from,to,subject,message){
          var datastr="from="+from+"&to="+to+"&subject="+subject+"&message="+message;
          return $.ajax({
              type: "POST",
              url: "mail.php",
              data: datastr,
              cache: false
          });
      }
      

      返回值implements the Promise interface,所以你可以这样做:

      $("#feedback").html("Sending email...");
      sendMail("from@email.com","to@email.com","MySubject","MyMessage")
          .done(function(){
              $("#feedback").html("Email sent.");
          })
          .fail(function(){
              $("#feedback").html("Error sending email.");
          });
      

      请注意,我从 ajax 调用中删除了 successerror 字段,因为它们不是必需的,但如果您需要它们用于其他用途,例如日志记录,您仍然可以使用它们。

      【讨论】:

      • 你得到了我要找的东西,但这不起作用:-(它会抛出这个错误“无法调用未定义的方法‘完成’”。我认为完成的方法应该只在延迟时使用对象。
      • 我找到了这个解决方案:$.when(sendMail("from@email.com","to@email.com","MySubject","MyMessage")) .done(function(){ $("#feedback").html("Email sent."); }) .fail(function(){ $("#feedback").html("Error sending email."); }); 但是有一个问题:done 和 fail 方法检查 sendMail 函数是否成功,而不是返回 true 或 false,所以即使它返回 false抛出“已发送电子邮件”:-(
      • 关于您的第一条评论,您是否也更改了sendMail 函数以使其返回ajax 调用的结果?关于您的第二条评论,如果您没有更改您的sendMail 函数,那么它将始终返回undefined$.when 将其视为“成功”值。如果您将行 $.ajax({ 更改为 return $.ajax({,则任何一个版本都应该工作。
      • 糟糕!我的错。在 $.ajax 之前没有看到返回 :-p 在这种情况下,您的解决方案效果很好。非常感谢。你帮了我很多。
      【解决方案3】:
      $("#feedback").html("Sending email...");
      $.ajax({
          type: "POST",
          url: "mail.php",
          data: datastr,
          cache: false,
          success: function(html){
             if (sendMail("from@email.com","to@email.com","MySubject","MyMessage")) {
                $("#feedback").html("Email sent.");
             } else {
                $("#feedback").html("Error sending email.");
             }
          },
          error: function(jqXHR,status,error){
              $("#feedback").html("Error sending email.");
          }
      });
      

      不知道 sendMail 是什么,但如果这是您检查电子邮件是否已发送,就这样吧?

      【讨论】:

      • 嗯...这应该可以,但我想重用 sendMail 功能。
      猜你喜欢
      • 2019-07-25
      • 2010-09-27
      • 2020-03-01
      • 2019-05-20
      • 2016-10-16
      • 1970-01-01
      • 2020-12-23
      • 1970-01-01
      • 2012-07-08
      相关资源
      最近更新 更多