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

Stripe订单金额计算函数异步问题:返回早于Map执行完成

问题原因
  1. map与await不兼容:items.map(async () => {})会返回一个由Promise组成的数组,但await只能等待单个Promise完成,无法直接等待整个Promise数组。因此await items.map(...)不会等待所有异步查询完成,就直接执行后续的console.log和return语句,导致总价计算不完整。
  2. 缺少await调用异步计算函数:在create-payment-intent接口中,调用calculateOrderAmount(items)和calculateAmount(items)时没有添加await,导致传入Stripe的是Promise对象而非实际计算出的金额数值,这不仅会导致金额错误,还可能引发Stripe API调用失败。
解决方案

1. 使用Promise.all等待所有异步操作完成

将map生成的Promise数组传入Promise.all,通过await等待所有商品价格查询完成后再进行总价累加。也可以结合reduce更优雅地处理累加逻辑,避免使用外部变量。

2. 在调用异步计算函数时添加await

确保create-payment-intent中传入Stripe的是实际计算出的金额数值,而非Promise对象。

修改后的代码
const express = require('express')
const mongoose = require('mongoose')
const stripe = require("stripe")(process.env.STRIPE_TEST_KEY);
const cors = require('cors')
const path = require("path");
const userRoutes = require('./routes/user')
const productRoutes = require('./routes/product')
const orderRouts = require('./routes/order')
const Product = require('./models/productModel')
require('dotenv').config()
const app = express()
app.use(cors())
app.use(express.json())
app.use(express.urlencoded({ extended: false }));
app.use("/images", express.static(path.join(__dirname, "images")));
app.use('/product', productRoutes)
app.use('/user', userRoutes)
app.use('/orders', orderRouts)

const calculateAmount = async (items) => {
    const _id = items[0].id
    console.log(_id)
    const product = await Product.findById({ _id })
    const price = items[0].amount * product.price
    console.log(price)
    return price * 100;
};

const calculateOrderAmount = async (items) => {
    // 使用Promise.all等待所有商品价格查询完成
    const itemPrices = await Promise.all(
        items.map(async (item) => {
            const product = await Product.findById(item.id);
            return item.amount * product.price;
        })
    );
    
    // 累加所有商品的总价
    const totalPrice = itemPrices.reduce((sum, price) => sum + price, 0);
    console.log(`total price is ${totalPrice}`)
    return totalPrice;
};

app.post('/create-payment-intent', async (req, res) => {
    const { items } = req.body;
    console.log(items)
    
    // 调用计算函数时添加await,确保拿到实际金额
    const amount = items.length > 1 
        ? await calculateOrderAmount(items) 
        : await calculateAmount(items);
    
    const paymentIntent = await stripe.paymentIntents.create({
        amount: amount * 100, // 统一转换为最小货币单位(分)
        currency: "cad",
        automatic_payment_methods: {
            enabled: true
        },
    });
    res.status(200).send({
        clientSecret: paymentIntent.client_secret
    })
})

mongoose.set("strictQuery", false)
mongoose.connect(process.env.MONGO_URL)
    .then(() => {
        app.listen(process.env.PORT, () => {
            console.log('listening on port', process.env.PORT)
        })
    })
    .catch((error) => {
        console.log(error)
    })
额外说明
  • Promise.all会并行执行所有异步查询,相比逐个等待(比如for...of循环)效率更高,适合无依赖的异步操作。
  • 使用reduce累加总价避免了外部变量的修改,代码更简洁且符合函数式编程风格。
  • 统一将金额乘以100转换为最小货币单位(分),符合Stripe API的参数要求,保持逻辑一致性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 10:25:54