javascript 识别最新的API调用响应并忽略旧的调用响应

fdx2calv  于 2023-06-28  发布在  Java
关注(0)|答案(2)|浏览(91)

我正在做一个搜索页面,用户在搜索输入文本框中输入文本,它会对每个字符更新的输入框文本进行 AJAX 调用,并更新UI。但我在识别最后一次API调用响应时遇到了问题。假设,用户输入'ABC',它正在进行三个API调用,

  1. A
    1.'AB'
  2. ABC
    我得到的回应是2,3,1。最后,UI显示的结果是“A”搜索文本,而不是“ABC”
    我不建议使用promise/async方法来解决这个问题,也不能在API调用中进行任何服务器端更改。
$.ajax({
    url: "search_api",
    success: function(){
    // update UI
    }
});
c90pui9n

c90pui9n1#

首先,无论何时对输入文本框进行更改,您都应该立即清空保存搜索结果的区域,作为进行AJAX调用的前奏。AJAX响应应该包括原始的搜索参数,如果该搜索参数当前不在输入文本框中,则应该丢弃响应。这样,返回响应的顺序就不重要了。输出搜索结果时,应禁用输入文本框,以确保输入文本框和搜索结果始终同步。当然,将以前的AJAX调用缓存在一个字典中,该字典的键是搜索参数,值是相应的搜索结果,这将使您不必进行额外的AJAX调用。
当您无法控制API调用的规范,并且不可能使用原始搜索参数标记响应时,需要采取激烈的措施:
首先,这甚至适用于原始的最佳情况,其中响应可以使用原始的搜索参数进行标记,您不应该在一段时间内没有击键活动之前进行API调用(例如半秒)。因此,如果用户是一个快速打字者,你应该等待,直到有一些暂停打字。否则,当响应返回时,它可能不再有效。在这种特殊情况下,原始的搜索参数不能在响应中返回,您将别无选择,只能进行调用,然后将任何其他请求推迟到当前AJAX调用完成时。这样,就永远不会有一个以上的未完成AJAX调用。当当前调用完成时,结果可能不再相关,因为输入文本框已更改,您将需要执行另一个API调用。您应该等待的键盘不活动持续时间将取决于系统响应AJAX调用的速度:你可以用更短的停顿来逃避,系统响应得越快。
我想得越多,就越觉得没有理由不能够将以任意顺序返回的多个异步响应绑定到原始请求。下面是一个使用jQuery的例子。我编写了一个echo服务器test4.py,它使用变量x发布,并简单地回显该值。函数make_request被传递参数x,并使用jQuery将其发布到echo服务器。当异步响应进来时,它能够通过使用ajax调用创建的请求对象上的done方法的回调参数的函数闭包将其绑定回原始请求参数:

function makeRequest(x) {
    var req = jQuery.ajax({
        'method': 'POST',
        'url': 'http://localhost/ron/test/test4.py',
        'data': {x: x}
        });
    req.done(function(msg) {
        console.log(msg +',' + x);
    });
}

done方法指定的回调函数只记录从echo服务器返回的消息和原始x参数。要启动文档就绪事件,我们有:

$(function() {
    for (let x = 0; x < 5; x++) {
        makeRequest(x);
    }
});

对日志的检查显示:

test2.html:16 4,4
test2.html:16 3,3
test2.html:16 1,1
test2.html:16 2,2
test2.html:16 0,0
bf1o4zei

bf1o4zei2#

好吧,我知道这个请求很老了,但下面是我发现在JavaScript模块的上下文中工作的方法:

counter = 0;

submitSearch() {
    ++this.counter;
    let localcounter = this.counter;
    let me=this;
    $.ajax({
        url: "search_api",
        success: function() {
            if (localcounter!=me.counter) {
               console.log('Ignore stale server response ' + localcounter);
            } else {
               // update UI
            }
        }
    });
}

我相信全局脚本在使用var和排除'this'时也会类似地工作:

var counter = 0;

function submitSearch() {
    ++ counter;
    let localcounter = counter;
    $.ajax({
        url: "search_api",
        success: function(){
            if (localcounter!=counter) {
               console.log('Ignore stale server response ' + localcounter);
            } else {
               // update UI
            }
        }
    });
}

相关问题