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

Node.js中调用两个异步函数用Await未返回预期值及超时需求

问题分析

  1. 结果集被修改/耗尽:getData中修改了resultset内部的rs.rows属性(将迭代器替换为数组),同时部分数据库驱动的结果集是一次性迭代资源,遍历后无法再次读取,导致后续convertToArray调用时无法获取数据,返回undefined。
  2. Promise反模式:exec和gues函数存在不必要的new Promise包裹——async函数本身已返回Promise,这种写法会增加代码复杂度和潜在异常。
  3. 参数传递缺失:原gues函数未接收resultset参数,调用exec时会传入未定义变量,直接导致执行失败。
  4. 缺少超时控制:未实现2分钟超时逻辑,无法在执行超时时主动抛出错误。

解决方案

1. 缓存结果集,避免重复消费/修改原对象

先将结果集转换为数组缓存,再基于缓存数据执行后续逻辑,彻底解决结果集被耗尽或修改的问题。

2. 移除Promise反模式,简化异步代码

利用async函数的原生特性,直接返回异步操作结果,无需额外包裹new Promise。

3. 实现超时控制

通过Promise.race将业务逻辑与超时Promise结合,达到2分钟自动报错的需求。


修改后的完整代码

重构工具函数(基于缓存数组操作)

// 重构getData:直接使用缓存的数组,避免修改原resultset
function getData(rows) {
  console.log(rows.length);
  return Promise.resolve(rows);
}

// 保留convertToArray核心逻辑:负责将原resultset转为数组缓存
function convertToArray(resultset) {
  return new Promise((resolve, reject) => {
    resultset.toObjArray(function (err, results) {
      if (err) {
        reject(err);
      } else {
        resolve(results);
      }
    });
  });
}

重构exec函数(添加超时+复用缓存)

function exec(resultset) {
  // 定义2分钟超时Promise(120000毫秒)
  const timeoutPromise = new Promise((_, reject) => {
    setTimeout(() => {
      reject(new Error("exec函数执行超时,已超过2分钟"));
    }, 120000);
  });

  // 业务逻辑:先缓存数组,再依次执行两个函数
  const businessLogic = async () => {
    const cachedRows = await convertToArray(resultset);
    await getData(cachedRows); // 执行getData逻辑
    return cachedRows; // 返回最终需要的结果
  };

  // 用Promise.race实现超时控制
  return Promise.race([timeoutPromise, businessLogic()]);
}

重构gues函数(修复参数传递+简化逻辑)

exports.gues = async function (resultset) {
  try {
    return await exec(resultset);
  } catch (err) {
    throw err;
  }
};

补充说明

  • 如果必须保留原getData对resultset的修改逻辑,建议先克隆resultset再传入(部分数据库驱动支持结果集克隆),避免修改原对象影响后续调用。
  • 若getData和convertToArray逻辑存在重复,可合并为一个函数减少冗余。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 02:37:51