当使用 jQuery 的 on() 绑定点击事件,并且在 AJAX 请求失败时需要自动重试,你可以采用以下几种方法:

方法一:使用递归重试机制

$(document).on('click', '#myButton', function() {
    var retryCount = 0;
    var maxRetries = 3;
    var retryDelay = 1000; // 1秒后重试
    
    function makeRequest() {
        $.ajax({
            url: 'your-api-endpoint',
            type: 'POST', // 或 'GET'
            data: { /* 你的数据 */ },
            success: function(response) {
                // 处理成功响应
                console.log('请求成功', response);
            },
            error: function(xhr, status, error) {
                if (retryCount < maxRetries) {
                    retryCount++;
                    console.log('请求失败,第 ${retryCount} 次重试...');
                    setTimeout(makeRequest, retryDelay);
                } else {
                    console.error('达到最大重试次数,请求失败', error);
                    // 可以在这里显示错误消息给用户
                }
            }
        });
    }
    
    makeRequest(); // 初始调用
});

方法二:使用 Promise 和 async/await(ES6+)

$(document).on('click', '#myButton', async function() {
    const maxRetries = 3;
    const retryDelay = 1000;
    
    for (let attempt = 1; attempt <= maxRetries; attempt++) {
        try {
            const response = await $.ajax({
                url: 'your-api-endpoint',
                type: 'POST',
                data: { /* 你的数据 */ }
            });
            
            console.log('请求成功', response);
            break; // 成功则退出循环
            
        } catch (error) {
            console.error('请求失败 (尝试 ${attempt}/${maxRetries})', error);
            
            if (attempt === maxRetries) {
                // 最后一次尝试也失败了
                alert('操作失败,请稍后再试');
                return;
            }
            
            // 等待延迟后继续下一次尝试
            await new Promise(resolve => setTimeout(resolve, retryDelay));
        }
    }
});

方法三:封装可重试的 AJAX 函数

// 封装可重试的 AJAX 函数
function retryAjax(options, maxRetries = 3, retryDelay = 1000) {
    return new Promise((resolve, reject) => {
        let retryCount = 0;
        
        function attempt() {
            $.ajax(options)
                .done(resolve)
                .fail(function(xhr, status, error) {
                    if (retryCount < maxRetries) {
                        retryCount++;
                        console.log('请求失败,第 ${retryCount} 次重试...');
                        setTimeout(attempt, retryDelay);
                    } else {
                        reject(error);
                    }
                });
        }
        
        attempt(); // 初始调用
    });
}

// 使用示例
$(document).on('click', '#myButton', function() {
    retryAjax({
        url: 'your-api-endpoint',
        type: 'POST',
        data: { /* 你的数据 */ }
    })
    .then(function(response) {
        console.log('请求成功', response);
    })
    .catch(function(error) {
        console.error('达到最大重试次数,请求失败', error);
        alert('操作失败,请稍后再试');
    });
});

高级功能:指数退避策略

对于更健壮的重试机制,可以使用指数退避策略:

$(document).on('click', '#myButton', function() {
    const maxRetries = 5;
    const initialDelay = 1000; // 初始延迟1秒
    let retryCount = 0;
    
    function makeRequest() {
        $.ajax({
            url: 'your-api-endpoint',
            type: 'POST',
            data: { /* 你的数据 */ },
            success: function(response) {
                console.log('请求成功', response);
            },
            error: function(xhr, status, error) {
                if (retryCount < maxRetries) {
                    retryCount++;
                    // 指数退避:延迟时间 = 初始延迟 * 2^(重试次数-1)
                    const delay = initialDelay * Math.pow(2, retryCount - 1);
                    console.log('请求失败,第 ${retryCount} 次重试将在 ${delay}ms 后执行...');
                    setTimeout(makeRequest, delay);
                } else {
                    console.error('达到最大重试次数,请求失败', error);
                    alert('操作失败,请稍后再试');
                }
            }
        });
    }
    
    makeRequest();
});

最佳实践建议

  1. 设置合理的重试次数:通常3-5次足够,避免无限重试

  2. 增加重试延迟:避免立即重试给服务器造成压力

  3. 考虑指数退避:对高并发系统更友好

  4. 用户反馈:在UI上显示重试状态或最终错误信息

  5. 区分可重试错误:某些错误(如400 Bad Request)不应重试

  6. 取消机制:如果用户离开页面,应取消未完成的重试

选择哪种方法取决于你的项目需求和技术栈(是否支持ES6+)。方法三的封装方式提供了最好的可重用性。