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

在map函数中调用Promise,Promise.all执行后仍为pending状态的问题求助

问题分析与解决方法

嘿,我一眼就看出问题所在啦!你当前的代码里,Promise.all并没有真正等待那些余额查询的Promise完成——原因出在你用map生成的数组结构上。

问题根源

你写的temp.map(x => [x, self.getBalance(x)])会生成一个数组嵌套数组的结构,比如:

[
  ['0x...', Promise { <pending> }],
  ['0x...', Promise { <pending> }]
]

而Promise.all的作用是等待数组里直接成员是Promise的对象完成。现在它看到的是一个个普通数组(不是Promise),所以直接把这些数组原样返回了,完全没去等待子数组里的Promise执行完毕。

修正方案(两种可选)

方案一:让每个map项返回一个Promise(推荐)

我们可以调整map的回调逻辑,让它返回一个Promise,这个Promise在余额查询完成后,会把「地址+余额」的数组作为结果resolve出来:

var prom = temp.map(x => 
  // 先等待getBalance完成,再把地址和余额组合成数组
  self.getBalance(x).then(balance => [x, balance])
);

Promise.all(prom).then(function(results) {
  console.log(results);
  // 这里的results会是类似:[['0x...', 2.5], ['0x...', 0.8]]
});

// 建议给getBalance的catch补充返回值,避免Promise.all异常
getBalance(t){
  return this.contract.methods.balanceOf(t).call()
    .then(function (result) {
      return result / Math.pow(10, 18);
    })
    .catch(function(e) {
      console.log('error: '+e);
      // 可以返回0作为默认值,或者抛出错误让Promise.all处理失败
      return 0;
      // 如果你想让Promise.all直接进入catch,就用:throw e;
    });
}

方案二:分开收集Promise再配对地址

如果你更习惯先分离地址和Promise,也可以先收集所有余额查询的Promise,完成后再和原始地址数组配对:

// 先收集所有余额查询的Promise
const balancePromises = temp.map(x => self.getBalance(x));

Promise.all(balancePromises).then(balances => {
  // 将地址数组和余额数组一一对应组合
  const results = temp.map((address, index) => [address, balances[index]]);
  console.log(results);
});

额外注意

你的getBalance方法里的catch块如果只打印错误而不返回值或抛出错误,会导致该Promise以undefined作为结果resolve。建议补充默认值(比如0)或者重新抛出错误,这样能让Promise.all的结果更可控。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:07:20