You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

筹款平台循环调用异步扣费函数的数据集同步问题咨询

这个问题我之前也碰到过!核心问题就是你的同步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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:30:26