猿问

如果用户提交新搜索,会中断搜索的执行吗?

我有一个文本字段,当用户键入时,AJAX 请求被发送到服务器以执行搜索并返回结果:


<input type="text" class="form-control player-list-control-text" id="name" name="name" autocomplete="off" />


$('.player-list-control-text').keyup(function(){

    get_player_list();

});


function get_player_list(){

    $.ajax({

        url: '/player/list/get',

        data: {

            'club_id' : $('#club_id').val(),

            'position_id' : $('#position_id').val(),

            'name' : $('#name').val(),

            'page' : players_page,

            'sort_by' : sort_by,

            'sort_order' : sort_order,

        },

        type: 'POST',

        success: function(result) {

            if(result.hasOwnProperty('error'))

                show_msg('error', result.error);

            else

                load_players(result);

        },

        error: function (response) {

            handle_error(response);

        }

    });

}

问题是,搜索需要一两秒的时间来执行,所以当用户快速输入,比如 5 个字符时,请求会变得混乱,要么需要很长时间,要么显示错误的结果 - 例如, 4 字母搜索的结果,而不是 5 字母搜索的结果。


我可以通过在客户端上保存请求时间或防止用户在处理前一个请求时输入来确保显示最后一个请求的结果,但这两种解决方案似乎都是不好的解决方案——第一个是因为它实际上并没有为服务器节省任何麻烦,第二次为糟糕的用户体验。


我真正在寻找的是一种在客户端发送新的 5 字母搜索查询时中断服务器上过时的 4 字母搜索中间执行的方法。


这可能吗?我该怎么办?


后端脚本包含多个查询,因为如果这完全相关,我们必须搜索多个表。


编辑:关于引发密切投票的类似问题,解决方案不是我所追求的。我想中断服务器端处理,而不仅仅是停止客户端上的请求。


慕容708150
浏览 122回答 2
2回答

呼如林

使用去抖动lodash的去抖动,而不是自己从头开始编写。const debouncedGetPlayerList = _.debounce(get_player_list, 2000);$('.player-list-control-text').keyup(function(){&nbsp; &nbsp; debouncedGetPlayerList(); // execute get_player_list after 2s non-interupted});现场示例:https ://codepen.io/dcorb/pen/mVGVOL$(document).ready(function(){&nbsp; var $statusKey = $('.status-key');&nbsp; var $statusAjax = $('.status-ajax');&nbsp; var intervalId;&nbsp;&nbsp;&nbsp; // Fake ajax request. Just for demo&nbsp; function make_ajax_request(e){&nbsp; &nbsp; &nbsp; var that = this;&nbsp; &nbsp; &nbsp; $statusAjax.html('That\'s enough waiting. Making now the ajax request');&nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; intervalId = setTimeout(function(){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;$statusKey.html('Type here. I will detect when you stop typing');&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;$statusAjax.html('');&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;$(that).val(''); // empty field&nbsp; &nbsp; &nbsp; },2000);&nbsp; &nbsp; }&nbsp;&nbsp;&nbsp; // Event handlers to show information when events are being emitted&nbsp; &nbsp; $('.autocomplete')&nbsp; &nbsp; &nbsp; .on('keydown', function (){&nbsp;&nbsp;&nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; $statusKey.html('Waiting for more keystrokes... ');&nbsp; &nbsp; &nbsp; clearInterval(intervalId);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; })&nbsp; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp; // Display when the ajax request will happen (after user stops typing)&nbsp; &nbsp; // Exagerated value of 1.2 seconds for demo purposes, but in a real example would be better from 50ms to 200ms&nbsp; $('.autocomplete').on('keydown',&nbsp; &nbsp; &nbsp; &nbsp;_.debounce(make_ajax_request, 1300));&nbsp; });body {&nbsp; &nbsp;background: #444444;&nbsp; &nbsp;color: white;&nbsp; &nbsp;font: 15px/1.51 system, -apple-system, ".SFNSText-Regular", "San Francisco", "Roboto", "Segoe UI", "Helvetica Neue", "Lucida Grande", sans-serif;&nbsp; &nbsp;margin:0 auto;&nbsp; &nbsp;max-width:800px;&nbsp; &nbsp;padding:20px;}form {&nbsp; display: inline-block;&nbsp; padding: 0;&nbsp; margin: 0;&nbsp; padding: 5px;&nbsp; margin: 5px 0 0 0;}input {&nbsp; padding:8px 20px;&nbsp; border-radius: 2px;&nbsp; border:0;&nbsp; font-size:20px;}.status-key,.status-ajax {&nbsp; margin:10px 0;}.status-ajax {&nbsp; color:#99FF7E;}<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script><form>&nbsp; <div class="status-key">Type here. I will detect when you stop typing</div>&nbsp; <input type="text" class="autocomplete">&nbsp; <div class="status-ajax"></div></form>

哆啦的时光机

延迟请求直到用户完成输入var timer;$('.player-list-control-text').keyup(function(){&nbsp; &nbsp; clearTimeout(timer);&nbsp; &nbsp; timer = setTimeout(function () {get_player_list();}, 500);});500ms 为您节省了很多无用的搜索输入请求。
随时随地看视频慕课网APP
我要回答