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

JavaScript异步函数中Await未等待及Promise返回异常问题求助

解决JavaScript异步与Promise使用问题

原始代码的核心问题

你的原始代码里,function1虽然标记为async,但内部的connection.query是回调式的异步操作,这个回调函数的执行时机是在查询完成后,而function1本身会直接返回一个已resolved的空Promise(因为async函数默认返回Promise,且你没有等待异步操作完成)。

同时,回调函数里的return只是回调自己的返回值,和function1的返回值无关。所以function2里调用function1()时,不会等待查询完成就直接执行console.log("Exit"),导致输出顺序颠倒。

Promise版本的问题

你尝试用Promise改造,但犯了两个关键错误:

  • customPromise是在connection.query的回调内部创建的,function1并没有返回这个Promise,所以await function1()得到的是undefined(async函数无return时默认返回Promise.resolve(undefined))。
  • 即使在then里返回了customPromise,这个返回值也属于回调函数的then链,不会成为function1的返回值。

正确的写法

第一步:将回调式的connection.query包装为Promise

首先把异步查询封装成Promise,这样就能用async/await来控制流程:

// 封装connection.query为Promise
function queryDatabase(query) {
  return new Promise((resolve, reject) => {
    connection.query(query, (error, result) => {
      if (error) {
        reject(error); // 出错时触发reject
        return;
      }
      resolve(result); // 成功时返回查询结果
    });
  });
}

第二步:重写function1和function2

现在可以用async/await来正确等待异步操作:

async function function1() {
  let query = "SELECT * FROM table1";
  try {
    const result = await queryDatabase(query); // 等待查询完成
    console.log("Length", result.rows.length);
    
    let result_query = [];
    let i = 0;
    while (i < result.rows.length) {
      result_query.push(result.rows[i]);
      i++;
    }

    if (result_query.length > 0) {
      return result_query; // async函数会自动把这个值包装成resolved的Promise
    } else {
      throw new Error('ERROR'); // 用throw触发Promise的reject
    }
  } catch (error) {
    throw error; // 抛出错误,让调用者处理
  }
}

async function function2() {
  try {
    const result = await function1(); // 等待function1执行完成
    console.log("Exit");
    // 直接使用查询结果,无需再调用then
    console.log("查询结果:", result);
  } catch (error) {
    console.error("执行出错:", error);
  }
}

// 启动执行
function2();

关键知识点总结

  • async函数的返回值:async函数总是返回一个Promise,如果return非Promise值,会自动包装为Promise.resolve(值);如果throw错误,会返回Promise.reject(错误)。
  • await的作用:只能在async函数内部使用,会等待右侧Promise完成并拿到resolved的值;若Promise被reject,会抛出错误,需要用try/catch捕获。
  • 回调转Promise:对于传统的回调式异步API,必须先封装成Promise才能用async/await,否则无法正确等待异步操作完成。

内容的提问来源于stack exchange,提问作者Sebastián

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 05:35:02