$.when配合带有ajax的函数

本文介绍了一种使用jQuery的$.when()方法实现异步加载与并行执行的策略。通过实例展示了如何定义和调用异步任务,并在所有任务完成后执行后续操作。这种方法可以提高应用程序的响应性和效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

app = {
    init(){
        $.when(
            this.loadXXX(),
            this.loadYYY()
        )
    },
    loadXXX(){
        let dtd = $.Deferred();
        $.ajax({
            ...,
            success:function(){
                dtd.resolve();
            }
        });
        return dtd;
    },
    loadYYY(){
        let date = "";
        return this.loadYYYHelper(date);
    },
    loadYYYHelper(){
        let dtd = $.Deferred();
        $.ajax({
            ...,
            success:function(){
                dtd.resolve();
            }
        });
        return dtd;
    }
}

其他信息自行百度

<think>我们遇到了在点击“结算”按钮时出现“请求失败,请重试”的问题。这通常是由于AJAX请求未能正确发送或处理引起的。为了诊断和解决这个问题,我们将采取以下步骤: 1. **检查AJAX请求是否被正确发送**:使用浏览器开发者工具(F12)查看网络请求,检查发送的AJAX请求的状态和响应。 2. **检查服务器端错误日志**:查看服务器的错误日志(例如,Apache的error.log或PHP的error_log),以确定是否有PHP错误。 3. **验证Nonce安全字段**:确保发送的nonce字段与服务器端验证的nonce一致。 4. **检查用户权限**:确保AJAX处理函数正确区分了登录用户和非登录用户(nopriv)。 5. **调试AJAX响应**:在AJAX响应中添加详细的错误信息。 ### 解决方案 #### 步骤1:增强AJAX处理函数的错误报告 修改`reliable_store_selected_items`函数,以提供更详细的错误信息。 ```php:functions.php (修改部分) function reliable_store_selected_items() { try { // 验证nonce if (!check_ajax_referer('woocommerce-cart', 'security', false)) { throw new Exception('安全验证失败。请刷新页面后重试。'); } // 验证输入 if (empty($_POST['selected_items']) || !is_array($_POST['selected_items'])) { throw new Exception('未接收到选中商品。请选择商品后重试。'); } $selected_items = array_map('sanitize_text_field', $_POST['selected_items']); // 验证购物车项是否存在 $cart = WC()->cart; if (is_null($cart)) { throw new Exception('购物车未初始化。'); } $cart_items = $cart->get_cart(); $valid_keys = array_keys($cart_items); $invalid_keys = array_diff($selected_items, $valid_keys); if (!empty($invalid_keys)) { throw new Exception('购物车中不存在以下商品:' . implode(', ', $invalid_keys) . '。请刷新购物车页面。'); } // 存储到会话 $session = WC()->session; if (is_null($session)) { throw new Exception('会话不可用。'); } $session->set('reliable_selected_items', $selected_items); wp_send_json_success(['message' => '商品已存储。']); } catch (Exception $e) { // 记录详细错误 error_log('部分结算错误: ' . $e->getMessage()); wp_send_json_error([ 'message' => $e->getMessage(), 'debug_info' => [ 'selected_items_received' => $_POST['selected_items'] ?? '未设置', 'cart_item_keys' => array_keys($cart_items ?? []) ] ]); } } ``` #### 步骤2:在JavaScript中添加详细的调试信息 修改前端的AJAX请求代码,以便在控制台输出详细的调试信息。 ```javascript:cart.php (修改部分) // 部分结算 $('#partial-checkout').click(function(e) { e.preventDefault(); const selectedKeys = $('.item-checkbox:checked').map(function() { return this.value; }).get(); if (selectedKeys.length === 0) { alert('<?php esc_attr_e('请至少选择一件商品结算', 'woocommerce'); ?>'); return false; } debugLog('发送部分结算请求', { action: 'store_selected_items', selected_items: selectedKeys, security: cartParams.cart_nonce }); const $btn = $(this); const originalText = $btn.html(); $btn.html('<?php esc_attr_e('处理中...', 'woocommerce'); ?>').prop('disabled', true); $.ajax({ type: 'POST', url: cartParams.ajax_url, data: { action: 'store_selected_items', selected_items: selectedKeys, security: cartParams.cart_nonce }, dataType: 'json', success: function(response) { debugLog('部分结算响应', response); if (response.success) { debugLog('重定向到结算页面'); window.location.href = $btn.attr('href'); } else { let errorMessage = response.data && response.data.message ? response.data.message : '<?php esc_attr_e('结算失败,未知错误。', 'woocommerce'); ?>'; // 显示详细的错误信息 alert(errorMessage); // 如果有调试信息,打印到控制台 if (response.data && response.data.debug_info) { debugLog('调试信息', response.data.debug_info); } $btn.html(originalText).prop('disabled', false); } }, error: function(xhr, status, error) { debugLog('AJAX请求失败', { status: status, error: error, responseText: xhr.responseText }); alert('<?php esc_attr_e('请求失败,请重试。错误信息:', 'woocommerce'); ?>' + error); $btn.html(originalText).prop('disabled', false); } }); }); ``` #### 步骤3:确保Nonce正确传递 在购物车页面,确保nonce正确生成并传递给JavaScript。检查`wp_localize_script`是否被正确调用。 #### 步骤4:检查用户权限 确保AJAX动作同时为登录用户和非登录用户注册: ```php add_action('wp_ajax_store_selected_items', 'reliable_store_selected_items'); add_action('wp_ajax_nopriv_store_selected_items', 'reliable_store_selected_items'); ``` ### 诊断步骤 1. **在浏览器中打开开发者工具(F12)**,切换到“网络(Network)”选项卡。 2. **尝试点击“结算选中商品”按钮**。 3. **查看网络请求**: - 找到名为`admin-ajax.php`的请求。 - 检查该请求的“状态(Status)”,如果是500,则表明服务器端有错误。 - 如果是200,则查看响应内容,里面可能有错误信息。 4. **检查响应内容**: - 如果响应是JSON格式,查看其中的`message`和`debug_info`字段。 5. **检查服务器错误日志**: - 根据服务器环境,找到错误日志文件(如Apache的error.log或PHP的error_log),查看是否有相关错误。 ### 常见问题及解决方案 - **问题:Nonce验证失败** 原因:页面缓存导致nonce过期,或者没有正确传递nonce。 解决:确保页面没有缓存,或者使用动态生成的nonce。 - **问题:购物车会话未初始化** 原因:在AJAX请求中,WooCommerce的购物车对象没有正确加载。 解决:在AJAX处理函数开始处添加以下代码: ```php if (!function_exists('WC')) { require_once ABSPATH . 'wp-content/plugins/woocommerce/woocommerce.php'; } if (!WC()->cart) { WC()->frontend_includes(); wc_load_cart(); } ``` - **问题:用户权限问题** 原因:非登录用户的AJAX请求没有被正确处理。 解决:确保使用`wp_ajax_nopriv_`钩子注册了处理函数。 ### 最终代码调整 如果上述步骤仍然不能解决问题,我们可以在AJAX处理函数中手动初始化WooCommerce: ```php:functions.php (在reliable_store_selected_items函数开头添加) function reliable_store_selected_items() { // 确保WooCommerce已加载 if (!class_exists('WooCommerce')) { wp_send_json_error(['message' => 'WooCommerce未加载']); return; } // 确保购物车已加载 if (!WC()->cart) { WC()->cart = new WC_Cart(); } // ... 原有代码 ... } ``` ### 总结 通过以上增强的错误处理和调试信息,我们可以更准确地定位问题。请按照诊断步骤收集信息,然后根据具体的错误信息进行修复。 §§相关问题§§: 1. 如何通过浏览器开发者工具诊断AJAX请求失败? 2. WooCommerce的nonce机制是如何工作的? 3. 在WooCommerce中,如何正确初始化和操作购物车对象? 4. 如何处理WordPress中AJAX请求的权限问题(包括登录用户和非登录用户)?</think>我理解您仍然遇到"请求失败"的问题。让我们深入解决这个AJAX请求失败的问题。以下是全面的解决方案: ## AJAX请求失败排查与解决方案 ### 1. 诊断工具与步骤 首先,我们需要收集更多信息来诊断问题。请将以下调试代码添加到您的`functions.php`中: ```php // 添加详细的AJAX调试信息 add_action('wp_ajax_store_selected_items', 'debug_store_selected_items', 5); add_action('wp_ajax_nopriv_store_selected_items', 'debug_store_selected_items', 5); function debug_store_selected_items() { // 保存原始POST数据 file_put_contents( WP_CONTENT_DIR . '/debug_partial_checkout.log', "[" . date('Y-m-d H:i:s') . "] AJAX请求:\n" . print_r($_POST, true) . "\n\n", FILE_APPEND ); // 检查会话状态 $session_status = session_status(); $session_debug = [ 'session_status' => $session_status, 'session_id' => session_id(), 'wc_session' => isset(WC()->session) ? '存在' : '不存在' ]; file_put_contents( WP_CONTENT_DIR . '/debug_partial_checkout.log', "会话状态:\n" . print_r($session_debug, true) . "\n\n", FILE_APPEND ); // 检查nonce验证 $nonce = isset($_POST['security']) ? $_POST['security'] : ''; $nonce_valid = wp_verify_nonce($nonce, 'woocommerce-cart'); file_put_contents( WP_CONTENT_DIR . '/debug_partial_checkout.log', "Nonce验证: " . ($nonce_valid ? '有效' : '无效') . "\n\n", FILE_APPEND ); // 检查购物车状态 if (function_exists('WC') && WC()->cart) { $cart_items = WC()->cart->get_cart(); file_put_contents( WP_CONTENT_DIR . '/debug_partial_checkout.log', "购物车内容:\n" . print_r(array_keys($cart_items), true) . "\n\n", FILE_APPEND ); } } ``` ### 2. 增强版AJAX处理函数(解决常见问题) ```php // 增强的存储选中商品函数 function reliable_store_selected_items() { try { // 确保WooCommerce核心功能已加载 if (!function_exists('WC') || !WC()->cart) { throw new Exception('WooCommerce未正确加载'); } // 确保会话可用 if (!WC()->session) { // 尝试初始化会话 if (!session_id()) { session_start(); } WC()->session = new WC_Session_Handler(); WC()->session->init(); } // 验证nonce $nonce = isset($_POST['security']) ? sanitize_text_field($_POST['security']) : ''; if (empty($nonce) || !wp_verify_nonce($nonce, 'woocommerce-cart')) { throw new Exception('安全验证失败,请刷新页面重试'); } // 验证输入 if (empty($_POST['selected_items']) || !is_array($_POST['selected_items'])) { throw new Exception('未接收到选中商品'); } $selected_items = array_map('sanitize_text_field', $_POST['selected_items']); // 验证购物车项是否存在 $cart_items = WC()->cart->get_cart(); $valid_keys = array_keys($cart_items); $invalid_keys = array_diff($selected_items, $valid_keys); if (!empty($invalid_keys)) { throw new Exception('购物车中不存在以下商品:' . implode(', ', $invalid_keys)); } // 存储到会话 WC()->session->set('reliable_selected_items', $selected_items); // 添加调试信息 $debug_info = [ 'status' => 'success', 'selected_count' => count($selected_items), 'first_item' => reset($selected_items), 'session_id' => WC()->session->get_customer_id() ]; wp_send_json_success($debug_info); } catch (Exception $e) { // 获取详细的错误信息 $error_data = [ 'message' => $e->getMessage(), 'post_data' => $_POST, 'php_version' => phpversion(), 'woocommerce_version' => defined('WC_VERSION') ? WC_VERSION : '未知', 'session_status' => session_status(), 'session_id' => session_id(), 'cart_keys' => isset($cart_items) ? array_keys($cart_items) : [] ]; // 记录完整错误日志 error_log('部分结算错误: ' . print_r($error_data, true)); wp_send_json_error([ 'message' => $e->getMessage(), 'debug' => $error_data ]); } } ``` ### 3. 增强前端AJAX请求(带重试机制) ```javascript // 增强的部分结算处理 $('#partial-checkout').click(function(e) { e.preventDefault(); const $btn = $(this); const originalText = $btn.html(); const checkoutUrl = $btn.attr('href'); const maxRetries = 2; let retryCount = 0; // 获取选中的商品 const selectedKeys = $('.item-checkbox:checked').map(function() { return this.value; }).get(); if (selectedKeys.length === 0) { alert('<?php esc_attr_e('请至少选择一件商品结算', 'woocommerce'); ?>'); return false; } // 显示加载状态 $btn.html('<span class="spinner is-active"></span> <?php esc_attr_e('处理中...', 'woocommerce'); ?>').prop('disabled', true); // 发送AJAX请求 function sendRequest() { $.ajax({ type: 'POST', url: cartParams.ajax_url, data: { action: 'store_selected_items', selected_items: selectedKeys, security: cartParams.cart_nonce }, dataType: 'json', timeout: 10000, // 10秒超时 success: function(response) { if (response.success) { debugLog('部分结算成功', response.data); // 添加延迟确保会话保存完成 setTimeout(function() { window.location.href = checkoutUrl; }, 500); } else { debugLog('部分结算失败', response.data); let errorMsg = response.data.message || '<?php esc_attr_e('结算失败', 'woocommerce'); ?>'; // 显示详细错误信息 if (cartParams.debug_mode && response.data.debug) { errorMsg += '\n\n调试信息:\n'; errorMsg += 'PHP版本: ' + response.data.debug.php_version + '\n'; errorMsg += 'WooCommerce版本: ' + response.data.debug.woocommerce_version; console.error('详细错误:', response.data.debug); } alert(errorMsg); $btn.html(originalText).prop('disabled', false); } }, error: function(xhr, status, error) { debugLog('AJAX错误', {status: status, error: error}); // 重试机制 if (retryCount < maxRetries) { retryCount++; debugLog(`重试请求 (${retryCount}/${maxRetries})`); setTimeout(sendRequest, 1000); // 1秒后重试 } else { alert('<?php esc_attr_e('请求失败,请重试。错误: ', 'woocommerce'); ?>' + error); $btn.html(originalText).prop('disabled', false); } } }); } // 首次发送请求 sendRequest(); }); ``` ### 4. 会话初始化增强 ```php // 确保会话正确初始化 add_action('wp_loaded', 'ensure_wc_session', 5); function ensure_wc_session() { if (!function_exists('WC') || !WC()->session) { return; } // 确保会话已启动 if (!WC()->session->has_session()) { WC()->session->set_customer_session_cookie(true); } } // 在AJAX请求中初始化会话 add_action('woocommerce_init', 'init_wc_session_for_ajax'); function init_wc_session_for_ajax() { if (defined('DOING_AJAX') && DOING_AJAX && !WC()->session->has_session()) { WC()->session->set_customer_session_cookie(true); } } ``` ### 5. 常见问题解决方案 #### 问题1: Nonce验证失败 **解决方案**: ```php // 在functions.php中添加 add_filter('nonce_life', 'extend_nonce_life'); function extend_nonce_life() { return 60 * 60 * 24; // 24小时 } ``` #### 问题2: 会话不持久 **解决方案**: ```php // 在wp-config.php中增加会话超时时间 define('WC_SESSION_COOKIE', 'wc_session_' . COOKIEHASH); define('WC_SESSION_EXPIRATION', 48 * 60 * 60); // 48小时 ``` #### 问题3: 用户特定问题 **解决方案**: ```php // 在functions.php中添加用户检测 add_action('template_redirect', 'check_user_capability'); function check_user_capability() { if (is_cart() && !current_user_can('edit_posts')) { // 为普通用户添加特殊处理 add_filter('wc_session_use_secure_cookie', '__return_false'); } } ``` ### 6. 完整调试流程 1. **启用调试模式**: ```php // 在wp-config.php中 define('WP_DEBUG', true); define('WP_DEBUG_LOG', true); define('WP_DEBUG_DISPLAY', false); define('SAVEQUERIES', true); ``` 2. **检查日志文件**: - `/wp-content/debug.log` - `/wp-content/debug_partial_checkout.log`(我们创建的) 3. **浏览器控制台检查**: - 在Chrome/Firefox中按F12 - 查看Console和Network标签页 - 检查admin-ajax.php请求的响应 4. **服务器错误日志**: - Apache: `/var/log/apache2/error.log` - Nginx: `/var/log/nginx/error.log` 5. **临时禁用插件**: ```php // 在functions.php中临时添加 add_action('init', function() { if (!is_admin()) { // 禁用所有插件(临时测试) remove_all_actions('woocommerce_loaded'); } }); ``` ### 7. 替代AJAX方法(如果问题仍然存在) ```php // 使用REST API替代admin-ajax.php add_action('rest_api_init', function() { register_rest_route('partial-checkout/v1', '/store-selected', [ 'methods' => 'POST', 'callback' => 'rest_store_selected_items', 'permission_callback' => '__return_true' ]); }); function rest_store_selected_items(WP_REST_Request $request) { $params = $request->get_params(); // 这里添加与reliable_store_selected_items相同的逻辑 // ... return new WP_REST_Response($response, 200); } ``` ```javascript // 前端使用REST API $('#partial-checkout').click(function(e) { e.preventDefault(); // 替换为REST端点 const restUrl = '<?php echo esc_url_raw(rest_url('partial-checkout/v1/store-selected')); ?>'; $.ajax({ url: restUrl, method: 'POST', data: { selected_items: selectedKeys }, // ...其余部分相同 }); }); ``` ## 问题解决流程图 ```mermaid graph TD A[点击结算按钮] --> B{请求失败?} B -->|是| C[检查浏览器控制台] C --> D{有错误信息?} D -->|是| E[根据错误信息修复] D -->|否| F[检查AJAX响应] F --> G{有JSON响应?} G -->|是| H[解析错误消息] G -->|否| I[检查服务器日志] I --> J{找到错误?} J -->|是| K[修复服务器错误] J -->|否| L[启用详细调试] L --> M[分析调试日志] M --> N[定位问题] N --> O[实施修复] B -->|否| P[成功!] ``` 如果按照以上步骤仍然无法解决问题,请提供以下信息: 1. 浏览器控制台中admin-ajax.php请求的完整响应 2. 服务器错误日志中的相关条目 3. WooCommerce和WordPress的版本号 4.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值