筹款平台循环调用异步扣费函数的数据集同步问题咨询
这个问题我之前也碰到过!核心问题就是你的同步for循环根本没等chargeDonations里的异步操作完成就开始下一次迭代了——两次调用同时去操作数据库,自然会出现数据不同步的问题。下面给你一步步解决:
问题根源
你原来的for循环是同步执行的,调用chargeDonations后不会等待它内部的数据库查询、数据集保存这些异步操作完成,直接就进入下一次循环。这导致两次chargeDonations同时读取和修改同一份数据,后一次操作拿到的还是前一次修改前的旧数据,最终出现重复扣费或者数据不一致的问题。
解决方案
要解决这个问题,我们需要把整个流程改成串行异步执行:每次chargeDonations执行完所有异步操作(包括数据库保存)后,再执行下一次循环迭代。具体分两步:
1. 把chargeDonations改成async函数
将函数内部的.then()链式调用改成await,让函数等待所有异步操作完成后再返回:
async function chargeDonations(proj_sub_id, price, quantity, fees) { // 用await替代.then()等待查询结果 const results = await wixData.query("Sponsorships") .eq("proj_sub_id", proj_sub_id) .ne("allFunds", true) .find(); let sponsorships = results.items; // 补全你遗漏的items属性 let toCharge = (price + fees); for (let i = 0; i < sponsorships.length; i++) { let amount_charged = sponsorships[i].amountCharged || 0; let remaining_sponsorship = sponsorships[i].amount - amount_charged; let net_amount = remaining_sponsorship - calculateFeesStripePhil(remaining_sponsorship, 1); let net_toCharge = toCharge + calculateFeesStripePhil(toCharge); // 手动累加总金额(替代原代码中可能错误的sum调用) let sponsorships_sum = sponsorships.reduce((sum, item) => sum + item.amount, 0); if ((toCharge - net_amount) > 0) { console.log("Donation Amount" + remaining_sponsorship); console.log("Net Amount" + net_amount); toCharge -= net_amount; console.log("Still to be Charged: " + toCharge); sponsorships_sum -= remaining_sponsorship; // 等待过滤器设置完成 await $w("#dataset2").setFilter( wixData.filter().eq("_id", sponsorships[i]._id) ); // 设置字段值 $w("#dataset2").setFieldValue('amountCharged', remaining_sponsorship + amount_charged); $w("#dataset2").setFieldValue('allFundsUsed', true); console.log("Saved Amount Charged"); // 等待数据库保存完成 await $w("#dataset2").save(); } else { console.log("Sponsorship Amount " + (toCharge / .921 - 0.3).toFixed(2)); console.log("Net Amount: " + toCharge); await $w("#dataset2").setFilter( wixData.filter().eq("_id", sponsorships[i]._id) ); $w("#dataset2").setFieldValue('amountCharged', toCharge + amount_charged); console.log("Saved Amount Charged"); await $w("#dataset2").save(); break; } } }
2. 用异步循环替代同步循环
原来的for循环是同步的,我们需要改成异步循环,确保每次chargeDonations完全执行完毕后再开始下一次:
// 用async函数包裹循环逻辑 async function processCharges() { for (let i = 0; i < 2; i++) { // 等待当前扣费流程全部完成 await chargeDonations(proj_sub_id, projItem.price, applications.length, project_fees); } } // 启动异步处理流程,并添加错误捕获 processCharges().catch(err => { console.error("扣费处理出错:", err); });
额外注意点
- 原代码中
let sponsorships = results.遗漏了items属性,Wix Data查询结果的数据集存在items字段中,必须补全才能正确获取数据。 - 原代码中的
sponsorships.sum("amount")用法有误,Wix Data的sum()需要在查询阶段指定(比如.sum("amount")),再通过results.sum获取,这里我改成了手动累加的方式,你可以根据实际需求调整。 - 一定要添加错误捕获逻辑,避免异步操作中的错误被静默忽略。
这样修改后,每次循环都会等待上一次的所有异步操作(包括数据库保存)完成后再执行,彻底解决数据不同步的问题。
内容的提问来源于stack exchange,提问作者David Seroy
相关产品推荐
相关产品推荐

