购物车Fetch更新时代金券商品数量与价格无法即时同步的修复求助
购物车Fetch更新时代金券商品数量与价格无法即时同步的修复求助
各位开发者大佬好,我在Shopify项目里开发购物车商品数量更新功能时,遇到了一个同步延迟的问题,想请大家帮忙看看怎么解决。
先简单说下背景:我基于现有的购物车数量更新逻辑(用fetch()调用cart_change_url),加了一个关联逻辑——当用户更新需要配套代金券的商品数量时,自动同步调整对应代金券的数量。
现在的问题是:代金券的数量和价格变化,无法在用户操作后即时显示在页面上,必须要等下一次操作(比如再改一次数量)才会更新,相当于页面显示总是慢一步。
下面是我的完整代码和修改部分:
完整的更新函数代码
updateMainItem(line, quantity, name, variantId) { const body = JSON.stringify({ line, quantity, sections: this.getSectionsToRender().map((section) => section.section), sections_url: window.location.pathname, }); fetch(`${routes.cart_change_url}`, { ...fetchConfig(), ...{ body } }) .then((response) => { return response.text(); }) .then((state) => { const parsedState = JSON.parse(state); const quantityElement = document.getElementById(`Quantity-${line}`) || document.getElementById(`Drawer-quantity-${line}`); const items = document.querySelectorAll('.cart-item'); // 👇 我的修改部分开始 const itemsNeedingVouchers = parsedState.items.filter((i) => i.properties?.Vouchers === "Yes"); const vouchers = parsedState.items.filter((i) => i.variant_id === 46396120596724); if (itemsNeedingVouchers && vouchers) { const updateVoucher = async (id, quantity) => { await fetch("/cart/update.js", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ updates: { [id]: quantity } }), }) .then((response) => { return response.text(); }) .then((responseText) => {}); }; for (const item of itemsNeedingVouchers) { const voucher = vouchers.find(v => v.properties?.["For Variant"] === String(item.id)); if (voucher) { updateVoucher(voucher.id, item.quantity); } else { updateVoucher(voucher.id, 0); } } } // 👇 我的修改部分结束 if (parsedState.errors) { quantityElement.value = quantityElement.getAttribute('value'); this.updateLiveRegions(line, parsedState.errors); return; } this.classList.toggle('is-empty', parsedState.item_count === 0); const cartDrawerWrapper = document.querySelector('cart-drawer'); const cartFooter = document.getElementById('main-cart-footer'); if (cartFooter) cartFooter.classList.toggle('is-empty', parsedState.item_count === 0); if (cartDrawerWrapper) cartDrawerWrapper.classList.toggle('is-empty', parsedState.item_count === 0); this.getSectionsToRender().forEach((section) => { const elementToReplace = document.getElementById(section.id).querySelector(section.selector) || document.getElementById(section.id); elementToReplace.innerHTML = this.getSectionInnerHTML( parsedState.sections[section.section], section.selector ); }); const updatedValue = parsedState.items[line - 1] ? parsedState.items[line - 1].quantity : undefined; let message = ''; if (items.length === parsedState.items.length && updatedValue !== parseInt(quantityElement.value)) { if (typeof updatedValue === 'undefined') { message = window.cartStrings.error; } else { message = window.cartStrings.quantityError.replace('[quantity]', updatedValue); } } this.updateLiveRegions(line, message); const lineItem = document.getElementById(`CartItem-${line}`) || document.getElementById(`CartDrawer-Item-${line}`); if (lineItem && lineItem.querySelector(`[name="${name}"]`)) { cartDrawerWrapper ? trapFocus(cartDrawerWrapper, lineItem.querySelector(`[name="${name}"]`)) : lineItem.querySelector(`[name="${name}"]`).focus(); } else if (parsedState.item_count === 0 && cartDrawerWrapper) { trapFocus(cartDrawerWrapper.querySelector('.drawer__inner-empty'), cartDrawerWrapper.querySelector('a')); } else if (document.querySelector('.cart-item') && cartDrawerWrapper) { trapFocus(cartDrawerWrapper, document.querySelector('.cart-item__name')); } publish(PUB_SUB_EVENTS.cartUpdate, { source: 'cart-items', cartData: parsedState, variantId: variantId }); }) .catch(() => { this.querySelectorAll('.loading__spinner').forEach((overlay) => overlay.classList.add('hidden')); const errors = document.getElementById('cart-errors') || document.getElementById('CartDrawer-CartErrors'); errors.textContent = window.cartStrings.error; }) .finally(() => { this.disableLoading(line); }); }
问题分析
我自己排查了一下,觉得问题应该出在异步请求的时序上:
- 页面的UI更新是基于第一次
cart_change_url返回的parsedState,这时代金券的数量还没更新; - 代金券的更新是在之后的异步
fetch('/cart/update.js')请求里,等这个请求完成时,页面已经完成了第一次渲染,所以最新的代金券状态没有同步到页面上; - 只有等下一次操作触发更新时,才会拿到包含代金券最新状态的购物车数据,页面才会显示正确的信息。
我尝试过的思路
我想过把代金券的更新改成同步,但await在原来的回调里好像没起作用,或者我用的方式不对?也想过在代金券更新完成后手动触发页面重新渲染,但不知道怎么调用现有的sections更新逻辑。
有没有大佬能帮我调整代码,让代金券的数量和价格能在用户操作后即时显示出来?
内容来源于stack exchange
相关产品推荐
相关产品推荐

