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

Node.js中如何在函数内调用另一个函数并通过Promise返回结果(MySQL)

如何用Promise改造异步数据库查询以获取返回值

你的代码里的核心问题是数据库查询是异步操作,getPaymentDetails里的return res其实是在回调函数里执行的,根本不会作为getPaymentDetails的返回值返回给调用者。Promise就是用来解决这类异步操作无法直接获取返回值的问题的,下面我给你一步步改造:

改造思路

  • 把异步的db.query封装成Promise,这样就能用async/await或者.then()来等待异步操作完成并获取结果
  • 让getPaymentDetails返回这个Promise,而不是依赖回调
  • 改造paymentDetails方法,因为它调用了异步的getPaymentDetails,所以也要改成异步函数来处理结果

完整改造后的代码

var payment = {
  // 封装db.query为Promise工具函数,复用性更高
  queryDB: function(sql, params) {
    return new Promise((resolve, reject) => {
      db.query(sql, params, function(err, res) {
        if (err) {
          reject(err); // 查询失败时抛出错误
        } else {
          resolve(res); // 查询成功时返回结果
        }
      });
    });
  },

  // 改造为async函数,用await处理异步逻辑
  paymentDetails: async function(data) {
    var order_id = data.order_id;
    try {
      // 等待第一个订单查询完成
      var orderRes = await this.queryDB(
        "select o.sku,p.published_on,sp.total_sale_price as amount, o.total_cost from orders o left join product p on p.sku = o.sku and p.is_published = 1 and p.is_deleted = 0 left join supplier_product sp on sp.product_id = p.product_id and sp.is_deleted = 0 and sp.active = 1 where o.order_id = ? and o.order_status < 13",
        [order_id]
      );
      var order_details = orderRes[0];

      // 等待支付详情查询完成
      var payment_details = await this.getPaymentDetails(order_id);

      // 这里可以按需组合结果并返回,也可以单独返回两个变量
      return { order_details, payment_details };
    } catch (err) {
      // 统一捕获所有异步操作的错误
      console.error('查询出错:', err);
      throw err; // 可选择抛出错误让调用者处理,或返回错误信息
    }
  },

  // 改造后返回Promise,不再依赖回调
  getPaymentDetails: function(order_id) {
    return this.queryDB(
      "select payment_type, amount, status from payment_details where payment_mode = 5 and invoice_type = 8 and status in ('success','pending_for_approval') and merchant_order_id = ?",
      [order_id]
    );
  }
};

module.exports = payment;

关键说明

  1. Promise封装:queryDB把原生回调式的db.query包装成了Promise,让所有数据库查询都能统一用异步语法处理,避免回调嵌套的混乱。
  2. async/await语法:给paymentDetails加上async关键字后,就能用await逐个等待异步操作完成,代码逻辑和同步代码几乎一致,可读性大幅提升。
  3. 错误统一处理:用try/catch块包裹所有异步操作,一次性捕获所有可能的错误,不用在每个回调里单独处理。
  4. 调用方式:现在paymentDetails返回的也是一个Promise,调用时需要用await或者.then()来获取结果:
    // 示例1:用.then()链式调用
    payment.paymentDetails({ order_id: 1001 })
      .then(result => {
        console.log('订单详情:', result.order_details);
        console.log('支付详情:', result.payment_details);
      })
      .catch(err => {
        console.error('处理失败:', err);
      });
    
    // 示例2:在async函数里用await调用
    async function handleOrderPayment(orderId) {
      try {
        const result = await payment.paymentDetails({ order_id: orderId });
        // 后续业务逻辑
      } catch (err) {
        console.error('处理出错:', err);
      }
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 10:01:23