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

服务器端点中使用await时出现变量值异常问题

问题分析与解决方案

嘿,我发现你的问题根本不是await的锅,而是浅拷贝在背后搞鬼!让我给你拆解清楚:

问题根源:浅拷贝导致嵌套对象引用共享

先看你的getOrderTemplate函数里这行代码:

const order = { ...order_template };

展开运算符...只能做浅拷贝——也就是说,它只会复制order_template的第一层属性。如果order_template是一个嵌套对象(比如里面包含recipient这个子对象),那么order.recipient其实和order_template.recipient指向的是同一个内存地址。

当你并发发送两个请求时,事件循环的执行顺序是这样的:

  1. 第一个请求进入/order接口,调用getOrderTemplate,把order.recipient.name改成name1,然后执行await takeTime()——这时候当前函数会暂停,事件循环去处理第二个请求。
  2. 第二个请求进来,同样调用getOrderTemplate,因为order.recipient是共享的引用,修改name为name2时,直接把第一个请求里的order.recipient.name也改成了name2!
  3. 等第一个请求的await结束后,再打印order.recipient.name,自然就变成了name2,这就是为什么你看到某个name只出现一次的原因。

解决方案:改用深拷贝

要解决这个问题,你需要对order_template做深拷贝,让每个请求都拿到完全独立的对象副本,不会互相干扰。这里有两种常用方法:

方法1:JSON序列化/反序列化(适合无特殊类型的对象)

如果order_template里没有函数、Date、Symbol这类无法被JSON序列化的类型,这种方法最简单:

function getOrderTemplate(shipping_info) { 
  // 用JSON序列化实现深拷贝
  const order = JSON.parse(JSON.stringify(order_template)); 
  order.recipient.name = shipping_info.first_name 
  order.recipient.address1 = shipping_info.address1 
  order.recipient.city = shipping_info.city 
  order.recipient.state_code = shipping_info.province_code 
  order.recipient.country_code = shipping_info.country_code 
  order.recipient.zip = shipping_info.zip 
  order.items = [] 
  order.packing_slip.email = "" 
  order.packing_slip.phone = "" 
  order.packing_slip.message = "Welcome!" 
  order.packing_slip.logo_url = "" 
  return order 
}

方法2:递归深拷贝函数(支持特殊类型)

如果order_template里有JSON无法处理的类型,可以自己写一个递归深拷贝函数:

// 递归深拷贝工具函数
function deepClone(obj) {
  // 非对象类型直接返回
  if (obj === null || typeof obj !== 'object') return obj;
  // 处理Date对象
  if (obj instanceof Date) return new Date(obj.getTime());
  // 处理数组
  if (obj instanceof Array) return obj.map(item => deepClone(item));
  // 处理普通对象
  const clonedObj = {};
  for (const key in obj) {
    if (obj.hasOwnProperty(key)) {
      clonedObj[key] = deepClone(obj[key]);
    }
  }
  return clonedObj;
}

function getOrderTemplate(shipping_info) { 
  const order = deepClone(order_template); 
  // 后面的代码保持不变...
  order.recipient.name = shipping_info.first_name 
  order.recipient.address1 = shipping_info.address1 
  order.recipient.city = shipping_info.city 
  order.recipient.state_code = shipping_info.province_code 
  order.recipient.country_code = shipping_info.country_code 
  order.recipient.zip = shipping_info.zip 
  order.items = [] 
  order.packing_slip.email = "" 
  order.packing_slip.phone = "" 
  order.packing_slip.message = "Welcome!" 
  order.packing_slip.logo_url = "" 
  return order 
}

验证效果

修改后,每个请求都会生成完全独立的order对象,修改recipient.name不会影响其他请求的对象。当两个请求并发执行时,你就能看到预期的输出——两个name1和两个name2(顺序可能因事件循环调度略有不同)。

内容的提问来源于stack exchange,提问作者Matteo Barberis

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 16:02:40