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

Promise.all未按预期执行,常量值意外累加问题求助

为什么Promise.all返回的结果中常量值出现累加?

我一看你这个问题就知道是对象引用传递在搞鬼!你期望每次调用testFN都基于初始的{"constant":"x"}生成新值,但实际上所有调用都在修改同一个对象,导致了累加的结果。

先给你拆解问题根源:

  • 你定义的var blob = {"constant":"x"};是一个对象,在JavaScript里,对象属于引用类型——当你把它作为参数传给testFN时,传递的不是对象的副本,而是指向这个对象的内存地址。
  • 然后在testFN里写的var newBlob = blob;根本没有创建新对象,只是让newBlob和blob指向了同一个内存里的对象。所以每次执行newBlob.constant = blob.constant+array.num,都是在修改原始blob对象的constant属性。

具体执行顺序一目了然:

  1. 第一次调用testFN:原始blob.constant是x,修改后变成x1,此时全局的blob已经被改变
  2. 第二次调用testFN:此时blob.constant已经是x1,加上2就变成x12
  3. 第三次调用:blob.constant是x12,加上3变成x123

这就是为什么你打印出来的是累加后的结果——所有testFN共享了同一个blob对象的引用。

解决方案:创建对象的独立副本

你只需要保证每次调用testFN时,传入的是一个新的对象副本,而不是同一个引用。有两种常用方式:

方式1:在调用testFN时创建副本

修改forEach里的代码,用对象展开运算符或者Object.assign生成新对象:

Object.keys(arr).forEach(function(key, i) {
  // 使用对象展开运算符创建新副本
  fnArr.push(testFN({...blob}, arr[key], i));
  // 或者用Object.assign实现同样效果
  // fnArr.push(testFN(Object.assign({}, blob), arr[key], i));
});

方式2:在testFN内部创建副本

如果你不想修改调用的地方,也可以在testFN里生成新对象:

function testFN(blob, array, iter){ 
  // 创建传入blob的副本,而非直接引用原始对象
  var newBlob = {...blob}; 
  // 或者用Object.assign({}, blob)
  newBlob.constant = blob.constant + array.num; 
  console.log(newBlob); 
  return products.findOneAndUpdate(....); 
}

这样每个testFN操作的都是独立的对象,不会互相干扰,就能得到你期望的x1、x2、x3结果了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:31:07