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

Promise在forEach循环后无法获取异步调用结果的问题排查

问题分析与解决方案

我明白你遇到的问题了——这是Promise新手常踩的异步时序坑!你的代码里,resolve(holdings)是在bittrex.getbalances的回调里直接执行的,但此时所有bittrex.getticker的异步请求还没完成,所以holdings还是空数组。而setTimeout只是靠延迟让异步请求碰巧完成,这完全是不可靠的“玄学修复”,我们得用Promise的正确方式来等待所有异步操作结束。

核心问题

你的Promise没有等待内部的getticker异步调用完成就提前resolve了。bittrex.getbalances和bittrex.getticker都是回调式的异步API,你需要把它们都Promise化,然后用Promise.all来等待所有异步任务结束后再返回结果。

修正后的代码

const bittrex = require('node.bittrex.api');
const { key, secret } = require('./key');

// 先把回调式的bittrex方法包装成Promise
const getBalancesPromise = () => {
  return new Promise((resolve, reject) => {
    bittrex.getbalances((data, err) => {
      if (err) reject(err);
      else resolve(data.result);
    });
  });
};

const getTickerPromise = (market) => {
  return new Promise((resolve, reject) => {
    bittrex.getticker({ market }, (ticker, err) => {
      if (err) reject(err);
      else resolve(ticker.result.Last);
    });
  });
};

// 主逻辑:用Promise.all等待所有异步任务
const getBalance = async () => {
  const balances = await getBalancesPromise();
  // 过滤出余额不为0的币种,同时生成对应的Promise数组
  const tickerPromises = balances
    .filter(coin => coin.Balance !== 0)
    .map(async (coin) => {
      const market = coin.Currency === 'BTC' ? 'USDT-BTC' : `BTC-${coin.Currency}`;
      const lastPrice = await getTickerPromise(market);
      return {
        Coin: coin.Currency,
        Balance: coin.Balance,
        Last: lastPrice
      };
    });

  // 等待所有ticker请求完成,得到最终的holdings数组
  return Promise.all(tickerPromises);
};

// 调用并输出结果
getBalance()
  .then((holdings) => {
    console.log(holdings);
  })
  .catch((err) => {
    console.error('出错了:', err);
  });

关键改动说明

  • Promise化回调API:把getbalances和getticker分别包装成返回Promise的函数,这样就能用await或者Promise.then来等待异步结果。
  • 使用async/await简化逻辑:主函数用async声明,内部用await等待余额请求完成,再对每个符合条件的币种发起ticker请求。
  • Promise.all等待所有异步任务:map返回的是一个Promise数组,Promise.all会等待所有Promise都resolve后,返回一个包含所有结果的数组,这时候的holdings就是完整的结果了。
  • 错误处理:新增了catch块来捕获整个流程中的错误,避免未处理的Promise rejection。

这样修改后,就不需要依赖setTimeout了,能可靠地等待所有异步网络请求完成后再返回正确的holdings数组。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:15:02