如何处理多个快速 jQuery ajax 提交

How to handle multiple fast jQuery ajax submissions

本文关键字:jQuery ajax 提交 何处理 处理      更新时间:2023-09-26

我的网站上有一个复选框列表。每次单击一个框时,ajax 脚本都会将数据提交到服务器并将条目状态保存在数据库中,然后在 done 方法上选中该框。

主要问题是当用户快速选中多个框时,其中大多数都没有被选中,更糟糕的是,有些保存在数据库中,有些则没有,以一种有点不可预测的方式。

关于如何处理这个问题的任何见解?我是否可以轻松地对请求进行排队,或者将所有请求合并为一个请求?我想要一些类似于谷歌保持网络界面的东西。

Polywhirl先生是对的,不要为每个操作发送一个请求。 相反,我会添加一个去抖动函数,该函数仅在上次调用该函数后经过 xxx 毫秒后触发一次。

大卫·沃尔什的去抖动函数(链接到上面):

function debounce(func, wait, immediate) {
    var timeout;
    return function() {
        var context = this, args = arguments;
        var later = function() {
            timeout = null;
            if (!immediate) func.apply(context, args);
        };
        var callNow = immediate && !timeout;
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
        if (callNow) func.apply(context, args);
    };
};

你应该能够像这样使用它:

var data = [];
var sendRequest = debounce(sendAjaxRequest, 200);
function sendAjaxRequest() {
    $.ajax({ /* Send Ajax Request */ });
    // Empty out the data array
    data = [];
}
// Add data to the array whenever your checkbox is clicked and 
// queue up the ajax request
$('.element').on('click', function() {
    data[] = $(this).data('my-data');
    sendRequest();
})

为了获得更好的用户体验,我会在用户单击该框时立即选中该框,并让请求匿名发送到服务器。否则,用户将不得不等待往返时间才能获得视觉反馈,这通常不是那么好。

但是,您可以轻松地实现一种"串行"执行请求的 queue:ing 方法,如下所示。(警告未经测试)

var queue = [];
var processing = false;
function queueRequest(data, cb){
    // Queue data to be send to the backend
    // Also cb will be called after it's done
    queue.push({
        data: data,
        cb: cb
    });
    processQueue();
}
function processQueue(immediate) {
    // If we have an empty queue, we are done!
    if (queue.length === 0) {
        processing = false;
        return;
    }
    if (!processing || immediate) {
        var item = queue.shift();   // Take first item
        processing = true;
        // Send the ajax  request
        $.ajax({
            url: "backend.com/checks",
            data: item.data,
            type: 'post',
            success: function(res) {
                if (typeof item.cb === "function")
                    cb(res);
                // Go on with the queue
                processQueue(true); // We call ourself, so it's "immediate"
            }
        });
    }
}

然后,您将要发送的数据排队,如下所示:

queueRequest({checkbox:5}, function(res){
    // Check the checkbox here, or do w/e you want
    // ...
});

在一个很酷的世界里,我会使用承诺而不是回调,但对于未经训练的 JS-eye 来说,这是一个更好的例子。

我会像这样处理这种情况:

用户复选框 -->框被选中 --> Ajax 触发 --> 如果响应成功,请保持选中状态;否则,取消选中并显示服务器响应中的错误