我有这个问题:
用户点击按钮 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/