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

Node.js异步场景下如何让if语句在binancePrice、coinbasePrice调用后执行

问题原因

你的代码问题本质是JavaScript异步执行逻辑:request 属于异步IO操作,调用binancePrice()和coinbasePrice()后,主线程不会等待请求返回,会直接往下执行价格判断的代码,此时两个接口的返回数据还没赋值,自然会报变量未定义的错误。
另外你用全局变量存储接口返回数据的写法有很大隐患,当多个用户同时请求接口时,全局变量会被不同请求的返回值覆盖,出现数据错乱。

可行方案

我们可以把回调形式的请求改造成返回Promise的形式,再用async/await+Promise.all并行请求两个接口,等两个请求都完成后再执行后续逻辑:

第一步:改写价格查询函数,返回Promise

// 请求币安BTC价格
function binancePrice() {
  return new Promise((resolve, reject) => {
    request(binanceAPI, (error, response, body) => {
      // 先处理请求报错的情况
      if (error) return reject(error)
      const binanceData = JSON.parse(body);
      if (!binanceData) {
        return reject(new Error('币安接口返回空数据'))
      }
      console.log(`币安最近${binanceData.mins}分钟的BTC价格为 ${binanceData.price}`);
      // 返回解析后的数据
      resolve(binanceData)
    })
  })
}

// 请求coinbase BTC价格
function coinbasePrice() {
  return new Promise((resolve, reject) => {
    request(coinbaseAPI, (error, resp, body) => {
      if (error) return reject(error)
      const coinbaseData = JSON.parse(body);
      if (!coinbaseData || !coinbaseData.data) {
        return reject(new Error('Coinbase接口返回数据异常'))
      }
      console.log(`Coinbase的BTC价格为 ${coinbaseData.data.amount} ${coinbaseData.data.currency}`);
      resolve(coinbaseData)
    })
  })
}

第二步:改写路由逻辑,等待两个请求完成后再执行判断

注意要给路由的处理函数加上async标记,同时添加异常捕获逻辑处理接口请求失败的情况:

// Router
testPay.route('/exchange-routing')
  .get(async (req, res) => {
    try {
      const cryptoAmount = parseFloat(req.query.amount, 10);
      let exchange = '';
      let price = 0;
      console.log(`用户选择的BTC数量为 ${cryptoAmount}`);

      if (cryptoAmount > 0) {
        // 并行发起两个请求,等两个都返回结果后再往下执行
        const [binanceData, coinbaseData] = await Promise.all([
          binancePrice(),
          coinbasePrice()
        ])

        const binancePriceVal = parseFloat(binanceData.price, 10)
        const coinbasePriceVal = parseFloat(coinbaseData.data.amount, 10)
        // 现在两个数据都已拿到,可以正常比较
        if (binancePriceVal > coinbasePriceVal) {
          exchange = 'Coinbase';
          price = coinbasePriceVal;
        } else {
          exchange = 'Binance';
          price = binancePriceVal;
        }
        // 返回结果给客户端
        const answer = {
          btcAmount: cryptoAmount,
          usdAmount: cryptoAmount * price,
          exchange,
        };
        res.json(answer);
      } else {
        res.send('BTC数量必须大于0');
      }
    } catch (err) {
      // 捕获所有异常,统一返回错误
      console.error('请求出错:', err)
      res.status(404).json({msg: '获取价格失败,请稍后重试'})
    }
  });

补充说明

  1. 你原来的代码里给Coinbase价格赋值时写的parseFloat(coinbaseData.price, 10)是错误的,根据你之前的打印逻辑,Coinbase的价格存在coinbaseData.data.amount里,上面的代码已经做了修正
  2. Promise.all会并行发起两个请求,比串行等待两个请求依次返回的效率更高
  3. 所有请求的异常都统一在路由的try catch里处理,避免接口无响应

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 16:51:01