【问题标题】:One button submits AJAX, another button queries result of that AJAX一个按钮提交 AJAX,另一个按钮查询该 AJAX 的结果
【发布时间】:2017-02-22 00:35:16
【问题描述】:

这个问题是我尝试学习 promises 和 deferreds 的一部分。假设您有一个提交POST 的按钮:

$("#submit").click( function() {
  $.post({...})
})

我的理解是 AJAX 本身就是一个承诺(这很明显),所以我想做的是,当用户点击 #check 时,它会在完成后返回 AJAX 的输出(假设#check 只能在点击 #submit 之后才会被点击。

我认为这很简单,所以我的初始代码是:

$("#check").click(function() {
  $.when($.post({...})).done( function(data) {
    console.log("data")
  })  
})

但我意识到,在这个实现中,AJAX 不会启动 POSTing,直到点击 #check。不需要任何 #submit 按钮,在 #submit 中使用 AJAX .post 是多余的。

有没有办法使用 promises/deferreds 来实现我正在做的事情?

【问题讨论】:

  • 目前还不清楚为什么需要两个按钮来执行一个 AJAX 请求。这似乎是一个等待发生的时间问题。为什么不直接将 .done() 附加到初始 AJAX 调用并在此处指定您要对响应执行的操作?
  • 您也可以考虑阻止默认提交操作,否则您的页面可能会在执行任何“.done”之前消失
  • 因为我只想在按下#check 后对响应采取行动......我该如何实现?
  • 就像一个 FYI James 一样,AJAX 不是一个承诺,它是一种异步发送和接收数据的机制。当然,可以说是通过包装它并返回对未来数据的承诺而不是使用传统的回调方法来改进它。
  • @rasmeister - jquery 长期以来一直从它的“ajax”系列函数中返回一个promise(排序,不是promise/A+ 规范,我称之为一个破碎的promise)——所以,不需要包装

标签: javascript jquery ajax promise jquery-deferred


【解决方案1】:

只存储post返回的promise。

var myPromise = null;
$("#submit").click( function() {
  myPromise = $.post({...});
});

$("#check").click(function() {
  if (myPromise) {
    myPromise.then( function(data) {
      console.log("data");
    });
  }
});

我所做的其他更改是使用 then() 而不是 done()(接受成功、失败或进度的单个函数),并且我添加了语句结尾的分号(因为自动插入分号会杀死小狗)。

一旦你完成了对 Promise 的研究,请迅速转到 observables。有了 JavaScript,乐趣就永远不会停止。

【讨论】:

  • 我不相信 $.post return 有一个 'then()'。可以使用 done() 还是 always()?
【解决方案2】:

基于对问题的评论:

我想通过 AJAX 提交一些东西,但是我想在单击按钮检查后才使用该 AJAX 的结果。

您可能过于复杂了。您真的不需要剖析 AJAX 请求/承诺/等。在这两个按钮之间。只需在第一个按钮中发出请求并存储结果,然后在第二个按钮中使用结果。就这么简单:

// disable the check button until there is a result to check
$('#check').prop('disabled', true);

var ajaxResult;

$("#submit").click( function() {
    $.post({...})
     .done(function (result) {
         // any other logic you want to put here, then...
         ajaxResult = result;
         $('#check').prop('disabled', false);
     });
})

$('#check').click(function() {
    // the result is in ajaxResult, use it as needed here
});

基本上,“检查”按钮与 AJAX 没有任何关系。它只是对内存中存在的数据执行操作。成功获取该数据后,该按钮就会被启用。

【讨论】:

  • 是的,但问题是我希望用户能够在没有要检查的结果时点击#check,然后等到该结果可用
【解决方案3】:

您可以在按下#submit 按钮时创建一个Promise,然后使用它为#check 按钮建立一个处理程序。

$("#submit").click(function() {
  var requestPromise = $.post( "xxx", function(response) {
    // do something here
  })
  .fail(function() {
     alert( "error" );
  })
  $("#check").click(function() {
    requestPromise.done(function(response) {
      // do something meaningful with response here, or other logic
    });
    // disable #check button and remove click handler here
  }
  // enable #check button here
})

编辑 - 应 OP 的要求

这是使用兼容 Promise 的版本:

    $("#submit").click(function() {
      var requestPromise = new Promise(function(resolve, reject) {
        $.post( "xxx", function(response) {
          // do something here
          resolve(response);
        })
        .fail(function(response) {
           alert( "error" );
           reject(response);
        });
      });
      $("#check").click(function() {
        requestPromise.then(function(response) {
          // do something meaningful with response here, or other logic
        });
        // disable #check button and remove click handler here
      }
      // enable #check button here
    })

【讨论】:

  • jquery ajax 函数返回一个promise,避免Promise 构造函数反模式
  • 我假设#check 按钮被禁用(这就是为什么在#submit 结束时单击他们启用它,是的,如果他们使用 jQuery ajax() 调用,那么他们可以使用psuedo-promise 。除了不需要创建新的 Promise 之外,逻辑基本保持不变。
  • 啊,是的,我现在看到了问题的一部分,即 #check 只能在 #submit 之后单击 - 付费阅读问题:p
  • 所以我也考虑过这个解决方案,但是围绕“承诺”的 Promise 构造函数的那一点让我很烦恼......但如果这是要走的路......我会测试出来
  • 我已经更新了答案,以展示一种使用 jQuery post() 响应作为伪承诺的方式。令人失望的是它不是一个合规的承诺,但它会在这种情况下发挥作用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-04
相关资源
最近更新 更多