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

Node+TS+Sequelize 数组map内OR运算符处理货币价格相加异常问题

错误根因

你的代码逻辑存在两个核心问题:

  1. 调用Crypto.findAll查询时仅指定了req.query.currency对应字段和createdAt作为返回属性,因此allPrices中每个price对象仅存在当前请求的货币属性,另外两个未查询的货币属性会返回null或undefined,转为数字后为0或NaN。
  2. JS逻辑或||运算符的执行规则是返回第一个真值,不管你当前请求的是哪种货币,都会先计算BTCUSD分支的结果,只要该结果的字符串不是空值(几乎所有场景下都满足),就会直接返回第一个分支的结果,永远不会触发后面ETHUSD、LTCUSD的计算逻辑,自然返回错误值。

修复方案

你已经通过req.query.currency拿到了当前请求的货币类型,直接用变量作为属性名取值即可,不需要写冗余的OR判断,同时建议先增加参数合法性校验,避免SQL注入风险,修改后代码如下:

const getHistorycalPrices = async (req: IGetHistorycalPricesRequest, res: IGetHistorycalPricesResponse) => {
  try {
    const allowedCurrencies = ['BTCUSD', 'ETHUSD', 'LTCUSD']
    // 先校验参数合法性
    if (!req.query.currency || !allowedCurrencies.includes(req.query.currency)) {
      res.status(400).send({
        success: false,
        message: "Could not get historycal prices",
      });
      return;
    }

    // Gets currency column by query from crypto DB table
    const allPrices = await Crypto.findAll({ attributes: [req.query.currency, 'createdAt'], order: [['createdAt', 'DESC']] });

    if (!allPrices) {
      res.status(400).send({
        success: false,
        message: "Could not get historycal prices",
      });
      return;
    }

    // Get first row from crypto DB table
    const firstRowPrices = await Crypto.findByPk(1);

    if (!firstRowPrices) {
      res.status(400).send({
        success: false,
        message: "Could not get first row prices",
      });
      return;
    }
    // 直接用动态属性名取值,不需要OR判断
    const currentCurrency = req.query.currency
    res.status(200).send({
      success: true,
      message: "Successfully retrieved historycal prices",
      data: allPrices.map((price) => ({
        cryptoPrices: (+price[currentCurrency] + +firstRowPrices[currentCurrency]).toString(),
        createdAt: price.createdAt.toDateString(),
      })),
    });
    return;
  } catch (e) {
    res.status(500).send({
      success: false,
      message: "Server error",
    });
    return;
  }
};

可选优化

如果需要避免字段空值导致计算结果异常,可以给取值逻辑增加兜底:

cryptoPrices: (+(price[currentCurrency] || 0) + +(firstRowPrices[currentCurrency] || 0)).toString()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 05:06:04