javascript - 如何处理本身被异步触发的异步ajax调用

标签 javascript jquery ajax asynchronous

我有这个问题:

用户点击按钮 A,然后通过 ajax 调用创建了一些东西。该调用返回一些数据。

稍后,用户(在输入中输入一些文本并)将单击按钮 B。这将启动另一个 ajax 调用。现在,这个需要从第一个请求返回的数据。

当第一次调用足够快时,这没有问题。但是,我必须假设这可能需要一段时间,因此当用户点击按钮 B 时,第一个调用可能无法完成。

只要第一个持续存在,我就不想禁用按钮 B。即使第一个 ajax 调用尚未完成,用户也应该单击按钮 B。所以看来我需要以某种方式将调用链接/排队。

我该怎么做?以及如何通过更长的调用序列来完成此操作。这种情况是否有名称,是否已有模式?还是我只是瞎了眼?

基本示例代码:

$('button.a').click(function () {
    $.post('some/url/for/action/a', {})
        .done(function (returnedData) {

        })
});

$('button.b').click(function () {
    // now I need something from returnedData, which may not be available yet
    $.post('some/url/for/action/b', {something: returnedData.something})
        .done(function () {

        })
});

注意:最终目标是加快改进用户体验的过程。

(请随意改进问题的标题。我无法表达得更好。)

最佳答案

如果您可以使用最新版本的 ECMAScript 规范,那么您可能想看看使用 Promises .有一个非常棒的explanation of Promises on Google's documentation for the web ,但它们基本上是我们可以用来等待事情异步完成的对象。

如果您将第一个 ajax 调用包装在一个 Promise 对象中,那么您稍后可以返回它(在您的例子中,在用户单击按钮 B 之后)并查看它是否已经完成。如果有,then() 您可以做一些响应!

var promiseA; // this variable will hold our Promise object

function postActionA() {
  return new Promise(function(resolve, reject) {
    $.post('some/url/for/action/a', {}).done(resolve); // this is the magic
    // when the ajax call completes, it calls the 'resolve' function
  });
}

$('button.a').click(function () {
  promiseA = postActionA();
  // by assigning our promise object to a variable
  // we can inspect its state later on
  promiseA.then(function(returnedData) {
    // do stuff with returnedData here if you like
  });
});

$('button.b').click(function () {
  // assuming that promiseA was assigned earlier
  // we can wait for it to resolve, then make our next ajax call
  promiseA.then(function (returnedData) {
    $.post('some/url/for/action/b', {something: returnedData.something})
      .done(function () {
      // do something after the second ajax call completes
      });
  });
});

如果您不能使用最新版本的 ECMAScript 而宁愿使用 jQuery,我们可以利用 jQuery 的延迟对象来做类似的事情。

var deferredA; // this variable will hold our Deferred object

$('button.a').click(function () {
  deferredA = $.post('some/url/for/action/a', {});
  // by assigning our deferred object to a variable
  // we can inspect its state later on
  deferredA.done(function(returnedData) {
    // do stuff with returnedData here if you like
  });
});

$('button.b').click(function () {
  // assuming that deferredA was assigned earlier
  // we can wait for it to resolve, then make our next ajax call
  deferredA.done(function (returnedData) {
    $.post('some/url/for/action/b', {something: returnedData.something})
      .done(function () {
      // do something after the second ajax call completes
      });
  });
});

关于javascript - 如何处理本身被异步触发的异步ajax调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41851779/

相关文章:

javascript - 拦截 switch default 或 case 中抛出的错误时的不同行为(React/Redux)

javascript - jQuery contains() 具有变量语法

javascript - 动态更改的元素未运行 JQuery 动画

angularjs - Angular 和 Ionic,$http 无法在 Android 真机上运行

javascript - 单击按钮(Web 应用程序)后执行什么脚本?

javascript - 更改 div 类 onclick --- 并*保存*更改

javascript - 使用 jQuery 从元素获取动态 css top 值

jquery - 按名称属性选择隐藏输入

javascript - 如何将 URL 放入 HTTP 请求中(作为查询字符串)?

php - AJAX Post 突然停止工作?