以与Ajax请求相同的顺序处理Ajax响应(Handle Ajax responses in same order as Ajax requests)

编程入门 行业动态 更新时间:2024-10-21 05:50:53
以与Ajax请求相同的顺序处理Ajax响应(Handle Ajax responses in same order as Ajax requests)

我想保护我的代码以确保用户操作按特定顺序触发的几个Ajax请求将以相同的顺序处理其响应。

我想保持Ajax的异步机制。 只需保护我的代码,以避免无序的响应,这可能导致我的网页上的混乱。

使它完全清楚。 我们举个例子:

$('#button1').click(function(){ $.ajax({url: 'dosomething1.html'}) .done( function(){ console.log('something 1 success'); } ) .fail( function(){ console.log('something 1 failure'); } ); }); $('#button2').click(function(){ $.ajax({url: 'dosomething2.html'}) .done( function(){ console.log('something 2 success'); } ) .fail( function(){ console.log('something 2 failure'); } ); }); $('#button3').click(function(){ $.ajax({url: 'dosomething3.html'}) .done( function(){ console.log('something 3 success'); } ) .fail( function(){ console.log('something 3 failure'); } ); });

如果用户点击“#button1”然后“#button2”然后“button3”,我想在控制台中看到:

>something 1 success >something 2 success >something 3 success

可能会发生响应未按服务器发送的顺序接收。 所以我想为这个场景做好准备。

注意:我事先无法知道用户触发的事件序列。 所以我需要找到一种方法来“动态”链接响应处理程序。

实现这一目标的最佳解决方案是什么?

我是Ajax狡猾的东西的新手,我今天读了大量的东西而没有找到解决方案(我想不知何故延迟和承诺对象可以做到这一点)。 请帮我摆脱这种可怕的头痛。 :)


编辑以通过Kevin B.评论解决方案

我努力了解我的大脑,完全理解Kevin B的例子(确实有效),直到我读了一本关于Deferreds的书,解释说“then”函数实际上是在创建一个新的Deferred并返回它的承诺。

这是与前一个“链接”的新承诺。 它根据先前的承诺评估结果(已解决或拒绝)调用其成功的失败回调。

在我们的情况下,这意味着当评估先前的承诺时,还会评估“then”承诺,并将先前承诺的结果(已解决或拒绝)作为输入,以决定调用哪个回调。 在kevin B的代码中,在两种情况下都会返回ajax请求承诺(已解决或拒绝)。 因此,仅在调用“then”承诺时调用promise的.fail和.done回调,并且返回的promise(ajax request one)被“解析”(.done函数)或被拒绝(.fail函数)。

更进一步:我的理解是,承诺是对未来可能发生的事件的一种倾听者。

在经典情况下,当事件发生时,延迟被更改为“已解决”或“已拒绝”状态,并且将调用promise回调。 承诺是“倾听”被延期的状态。 触发此状态更改的事件是解决或拒绝初始事件(ajax请求,超时,其他......)。

在“then”案例中,用于评估承诺的trigerring事件是:评估引用的承诺(链中的先前承诺)(解决或拒绝)。 给定评估结果,调用成功或失败回调。

我提出这个稍微重新组织的代码,灵感来自Kevin的代码,以帮助像我这样的假人更好地理解:

var currentPromise = $.Deferred().resolve().promise(); $('#button1').click(function(){ var button1Promise = $.ajax({url: 'dosomething1.html'}) var thenPromise = currentPromise.then( function () { return button1Promise;}, function () { return button1Promise;}); // to also handle fail conditions gracefully currentPromise = thenPromise; // "thenPromise" callback functions are returning the promise linked to // the ajax request. So this promise is "replacing" the "thenPromise". // Hence "done" and "fail" functions are finally defined for the ajax request promise. thenPromise.done( function(){ console.log('something 1 success'); } ); thenPromise.fail( function(){ console.log('something 1 failure'); } ); });

希望它能帮助那些不完全理解jquery概念的人完全理解用“then”函数链接的promises。

如果我误解了某些东西,请毫不犹豫地发表评论。

I would like to secure my code to make sure several Ajax requests triggered by user actions in a certain order will have their responses handled in the same order.

I want to keep the asynchonous mechanism of Ajax. Just secure my code to avoid out of sequence responses that can lead to mess on my web page.

To make it perfectly clear. Let's take an example:

$('#button1').click(function(){ $.ajax({url: 'dosomething1.html'}) .done( function(){ console.log('something 1 success'); } ) .fail( function(){ console.log('something 1 failure'); } ); }); $('#button2').click(function(){ $.ajax({url: 'dosomething2.html'}) .done( function(){ console.log('something 2 success'); } ) .fail( function(){ console.log('something 2 failure'); } ); }); $('#button3').click(function(){ $.ajax({url: 'dosomething3.html'}) .done( function(){ console.log('something 3 success'); } ) .fail( function(){ console.log('something 3 failure'); } ); });

If the user clicks on "#button1" then "#button2" and then "button3", I want to see in the console:

>something 1 success >something 2 success >something 3 success

It can happen that the responses are not received in the order the server sent them. So I want to get prepared for this scenario.

Note: I can't know in advance the sequence of events triggered by the user. So I need to find a way to chain the response handlers "on the fly".

What would be the best solution to achieve this?

I'm new to Ajax tricky stuff and I read a large amount of things today without finding THE solution (I guess that somehow deferred and promise objects could do the trick). Please help me to get rid of this terrible headache. :)


Edit to comment the solution by Kevin B.

I struggled with my brain to FULLY understand the example from Kevin B (that does work) until I read a book on Deferreds that explains that the "then" function is actually creating a new Deferred and returns its promise.

This is this new promise that is "chained" to the previous one. It calls its successfull of failure callbacks depending on the result of the previous promise evaluation (resolved or rejected).

In our case that means that when the previous promise is evaluated, the "then" promise is also evaluated and takes as an input the result (resolved or rejected) of the previous promise to decide which callback to call. In kevin B's code the ajax request promise is returned in both cases (resolved or rejected). Hence, the .fail and .done callback of the promise are called ONLY ONCE the "then" promise is evaluated AND the returned promise (ajax request one) is "resolved" (.done function) or rejected (.fail function).

To go further: My understanding is that the promise is a kind of listener on an event that can potentially happen in the future.

In classical cases, when the event happens, the deferred is changed to "resolved" or "rejected" state and the promise callbacks are called. The promise is "listening" to the state of the deferred to be changed. The event trigerring this state change is the resolution or rejection of the initial event (ajax request, timeout, other...).

In "then" cases, the trigerring event for evaluating the promise is: the referenced promise (previous promise in the chain) is evaluated (either resolved or rejected). Given the evaluation result, the success or failure callback is called.

I propose this slightly re-organized code inspired by Kevin's code to help out dummies like me to better understand:

var currentPromise = $.Deferred().resolve().promise(); $('#button1').click(function(){ var button1Promise = $.ajax({url: 'dosomething1.html'}) var thenPromise = currentPromise.then( function () { return button1Promise;}, function () { return button1Promise;}); // to also handle fail conditions gracefully currentPromise = thenPromise; // "thenPromise" callback functions are returning the promise linked to // the ajax request. So this promise is "replacing" the "thenPromise". // Hence "done" and "fail" functions are finally defined for the ajax request promise. thenPromise.done( function(){ console.log('something 1 success'); } ); thenPromise.fail( function(){ console.log('something 1 failure'); } ); });

Hopefully it will help people not totally comfortable with jquery concepts to fully understand promises chaining with "then" function.

Don't hesitate to comment if I misundertood something.

最满意答案

如果你预先创建一个承诺,你可以继续链接它以获得你想要的效果。

// ajax mock
function sendRequest(v, delay) {
    var def = $.Deferred();
    setTimeout(function () {
        def.resolve(v);
    }, delay);
    return def.promise();
}

var ajaxPromise = $.Deferred().resolve().promise();
var delay = 600; // will decrement this with each use to simulate later requests finishing sooner

// think of this as a click event handler
function doAction (btnName) {
    delay -= 100;
    var promise = sendRequest(btnName, delay);
    ajaxPromise = ajaxPromise.then(function () {
        return promise;
    }).done(function () {
        console.log(btnName);
    });
}

doAction("1");
doAction("2");
doAction("3"); 
  
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> 
  
 

由于我将它们延迟了500毫秒,400毫秒和300毫秒,所以它们都没有记录到500毫秒之后。

这是你的代码使用相同的技术:

var ajaxPromise = $.Deferred().resolve().promise(); $('#button1').click(function(){ var promise = $.ajax({url: 'dosomething1.html'}) ajaxPromise = ajaxPromise.then(function () { return promise; }, function () { return promise; // to also handle fail conditions gracefully }).done( function(){ console.log('something 1 success'); } ) .fail( function(){ console.log('something 1 failure'); } ); }); // repeat for other two buttons

重要的是所有的ajax请求将始终立即发送,但完成和失败的处理程序将在轮到他们之前执行。

If you create a promise up front, you could keep chaining off of it to get your desired effect.

// ajax mock
function sendRequest(v, delay) {
    var def = $.Deferred();
    setTimeout(function () {
        def.resolve(v);
    }, delay);
    return def.promise();
}

var ajaxPromise = $.Deferred().resolve().promise();
var delay = 600; // will decrement this with each use to simulate later requests finishing sooner

// think of this as a click event handler
function doAction (btnName) {
    delay -= 100;
    var promise = sendRequest(btnName, delay);
    ajaxPromise = ajaxPromise.then(function () {
        return promise;
    }).done(function () {
        console.log(btnName);
    });
}

doAction("1");
doAction("2");
doAction("3"); 
  
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> 
  
 

Since i delayed them by 500ms, 400ms, and 300ms, none of them logged until after 500ms.

Here's your code with the same technique:

var ajaxPromise = $.Deferred().resolve().promise(); $('#button1').click(function(){ var promise = $.ajax({url: 'dosomething1.html'}) ajaxPromise = ajaxPromise.then(function () { return promise; }, function () { return promise; // to also handle fail conditions gracefully }).done( function(){ console.log('something 1 success'); } ) .fail( function(){ console.log('something 1 failure'); } ); }); // repeat for other two buttons

The important thing is all of the ajax requests will always be sent immediately, but the done and fail handlers won't be executed until their turn.

更多推荐

本文发布于:2023-07-08 20:01:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1080258.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:顺序   Handle   Ajax   requests   order

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!