使用 Promise 和 .then() 解决同异步问题

在购物车功能中,用户点击"加入购物车"或"删除购物车"时,可能会遇到数据同步问题。例如,当用户快速连续点击"删除"按钮时,可能会导致删除操作基于过时的数据,从而引发错误。为了解决这个问题,我们可以使用 Promise.then() 来确保异步操作的顺序执行。

1. 问题描述

在购物车功能中,用户点击"删除购物车"按钮时,系统需要先获取最新的商品 ID,然后再执行删除操作。如果这两个操作是异步的,且没有正确的顺序控制,可能会导致删除操作基于过时的数据,从而引发错误。

2. 解决方案

我们可以将购物车数据刷新操作封装为一个返回 Promise 的函数 cartRefresh。该函数会在数据刷新完成后返回最新的商品 ID。然后,在删除购物车商品时,我们先调用 cartRefresh 获取最新的商品 ID,然后再执行删除操作。

3. 代码实现
3.1 cartRefresh 函数
javascript 复制代码
function cartRefresh(uid) {
    return new Promise((resolve, reject) => {
        $.ajax({
            type: "post",
            url: path + "/mobile/shopping",
            data: {
                id: userId
            },
            success: function (results) {
                if (results.code === 1) {
                    cartData = results.data;
                    let $id;
                    for (let i = 0; i < cartData.length; i++) {
                        if (cartData[i].commodity_id == uid) {
                            $id = cartData[i].id;
                            break; // 找到后立即退出循环
                        }
                    }
                    console.log('cartRefresh 成功,$id =', $id);
                    resolve($id); // 返回 $id
                }
            },
            error: function (e) {
                console.log('cartRefresh 失败:', e.status);
                reject(e); // 返回错误
            }
        });
    });
}
3.2 cartDel 函数
javascript 复制代码
function cartDel(data) {
    $('#commendContent').on('click', '.goodsImg', function (e) {
        let goodsBox = $(e.target).closest('.shops');
        let idElement = goodsBox.find('.goodsImg');
        let uid = idElement.attr('uid');
        if (idElement.attr('src') == './img/ok.png') {
            console.log(`删除`);
            cartRefresh(uid)
                .then((newId) => {
                    console.log('cartRefresh 返回的 $id:', newId);
                    // 在这里使用 newId
                    $.ajax({
                        type: 'post',
                        url: path + '/mobile/shopping/del',
                        data: {
                            id: newId // 使用当前的 $id
                        },
                        success: function (results) {
                            if (results.code === 1) {
                                idElement.attr('src', './img/add.png');
                                idElement.attr('ids', ''); // 清空购物车 ID
                                console.log(idElement);
                            }
                        },
                        error: function (e) {
                            console.log(e.status);
                        },
                    });
                })
                .catch((error) => {
                    console.error('cartRefresh 失败:', error);
                });
        } else if (idElement.attr('src') == './img/add.png') {
            console.log(`新增`);
            $.ajax({
                type: 'post',
                url: path + '/mobile/shopping/add',
                data: {
                    user_id: userId,
                    commodity_id: uid,
                    num: 1
                },
                success: function (results) {
                    if (results.code === 1) {
                        idElement.attr('src', './img/ok.png');
                    }
                },
                error: function (e) {
                    console.log(e.status);
                },
            });
        }
    });
}
4. 代码解析
  • cartRefresh 函数 :该函数通过 $.ajax 请求获取最新的购物车数据,并返回一个 Promise。在请求成功时,解析购物车数据并找到对应的商品 ID,然后通过 resolve 返回该 ID。如果请求失败,则通过 reject 返回错误。

  • cartDel 函数 :该函数监听购物车商品的点击事件。当用户点击"删除"按钮时,首先调用 cartRefresh 函数获取最新的商品 ID,然后在 .then() 中执行删除操作。如果 cartRefresh 失败,则通过 .catch() 捕获错误并输出日志。

5. 优点
  • 数据同步 :通过 Promise.then() 确保删除操作基于最新的购物车数据,避免了数据同步问题。

  • 代码可读性 :将异步操作封装为 Promise,使代码结构更加清晰,易于维护。

  • 用户体验:确保每次操作都基于最新数据,提高了用户体验。

6. 总结

通过使用 Promise.then(),我们能够有效地解决购物车功能中的数据同步问题,确保每次操作都基于最新的数据。这种设计不仅提高了代码的可读性和可维护性,还提升了用户体验,避免了因数据不同步而引发的错误。

希望这篇博客对你有所帮助!如果有任何问题或建议,欢迎留言讨论。

相关推荐
这可不简单2 分钟前
方便易懂的自适应方案---echarts和dom样式大小自适应
前端·vue.js·echarts
玲小珑4 分钟前
Auto.js 入门指南(七)定时任务调度
android·前端
橘黄的猫4 分钟前
深入解析 import.meta.url:与 new URL() 的关系及 Vite 中的 base 路径影响
前端·vite
海的诗篇_8 分钟前
前端开发面试题总结-HTML篇
前端·面试·html
Sun_light15 分钟前
用原生 HTML/CSS/JS 手把手带你实现一个美观的 To-Do List 待办清单小Demo
前端·css·html
用户214118326360217 分钟前
dify案例分享--告别手工录入!Dify 工作流批量识别电子发票,5分钟生成Excel表格
前端·人工智能
SweetRetry18 分钟前
前端依赖管理实战:从臃肿到精简的优化之路
前端·人工智能
LaoZhangAI19 分钟前
Claude Code完全指南:2025年最强AI编程助手深度评测
前端·后端
卸任21 分钟前
Electron自制翻译工具:增加中英互译
前端·react.js·electron
LaoZhangAI23 分钟前
FLUX.1 Kontext vs GPT-4o图像编辑全面对比:2025年最全评测指南
前端·后端