JS AJAX预先输出结果排序/竞争条件

时间:2016-02-03 14:32:42

标签: javascript jquery angularjs ajax race-condition

我遇到了AJAX typeahead / live-update as-you-type视图的问题,这些视图无序返回结果。有没有人对处理此问题的方法有任何经验?

问题:

  1. 输入查询,例如"搜索字词"。
  2. 即使进行了一些去抖动,也可能会在您输入时触发一些AJAX调用,例如"sea""search term"
  3. sea的搜索结果集大于search term的搜索结果集,因此其AJAX请求实际上在较新的查询后完成。
  4. 由此产生的问题:您输入search term,但正确的结果会在屏幕上显示一秒钟,但只会被sea的结果替换。
  5. Bare-bones jQuery伪代码:

    $('body').on('keyup', '#searchBox', function(){
        query = $("#searchBox").val();
        $.ajax({
            type: 'GET',
            url: '/endpoint.php?query=' + query,
            success: function (response) {
                // Update view here
                $("#view").html(response.text);
            }
       });
    });
    

    角度伪代码:

    // HTML
    <input ng-keyup = "search()" ng-model="searchBox" placeholder = "Search">
    {{results}}
    
    // JS
    $scope.search = function(){
        $http({
            method: 'GET',
            url: '/endpoint.php?query=' + $scope.searchBox
            }).then(function successCallback(response) {
                $scope.results = response.data;
            }, function errorCallback(response) {
                console.log(response);
            });
    }
    

1 个答案:

答案 0 :(得分:1)

最好停止比赛条件你可以保留对你做的最后一个AJAX请求的引用,然后在按下新键时abort()。在发出请求之前放置延迟也是值得的,这样你就不会发送每个按键的请求,而是在输入结束时。试试这个:

var previousRequest, previousTimer;

$('body').on('keyup', '#searchBox', function() {
    previousRequest && previousRequest.abort();
    clearTimeout(previousTimer);

    previousTimer = setTimeout(function() {
        previousRequest = $.ajax({
            type: 'GET',
            url: '/endpoint.php',
            data: { 
                query: $("#searchBox").val() 
            },
            success: function (response) {
                // Update view here
                $("#view").html(response.text);
            }
        });
   }, 200);
});
击键之间的距离很长,但是如果你想提高请求的响应速度,你可以缩短。