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

将返回Promise的函数转为async/await后,如何返回响应体?

问题:Promise转async/await后无法返回响应体?

我正尝试将一个返回Promise的函数转换为使用async/await的形式(我了解async函数会隐式返回Promise)。该函数封装了对https.request的调用,原Promise函数通过resolve(body)返回响应体且运行正常。但转为async/await形式后,我无法找到返回响应体的方法,请问我遗漏了什么?

原Promise函数代码

promise_it = (data) => {

  // throws FATAL
  if (!data) {throw new Error('data is missing');}

  return new Promise((resolve, reject) => {

    let postData = JSON.stringify(data);

    let options = {
      hostname: 'httpbin.org',
      port: 443,
      path: '/post',
      method: 'POST',
      headers: {
        // 'Content-Type': 'application/json',
        // Accept: 'application/json'
          'Content-Type': 'application/x-www-form-urlencoded',
          'Content-Length': postData.length
        }
    };
    
    const https = require('https');
    let req = https.request(options, (res) => {
    
      let body = [];
      res.on('data', function(chunk) {
          body.push(chunk);
      });
      res.on('end', function() {
    
        try {
            body = JSON.parse(Buffer.concat(body).toString());
            }
        catch(e) {
            console.error(e.message)
            reject(e);
        }
    
        resolve(body);

      });
    
    });
    
    req.on('error', (e) => {
      console.error(e);
      reject(e)
    });
    
    req.write(postData);
    req.end();

  });

}
    
  try {
    data = {firstName: 'Donald', lastName: 'Duck'}
    const who = promise_it(data)
    who
      .then(r => console.info('INFO:',r))
      .catch(e => console.error('ERROR:',e));
  } 
  catch (error) {
    console.error('FATAL:',error)  
  }

改写后的async/await函数代码

async_it = async (data) => {

  if (!data) {throw new Error('data is missing');}

  let postData = JSON.stringify(data);

  let options = {
      hostname: 'httpbin.org',
      port: 443,
      path: '/post',
      method: 'POST',
      headers: {
      // 'Content-Type': 'application/json',
      // Accept: 'application/json'
          'Content-Type': 'application/x-www-form-urlencoded',
          'Content-Length': postData.length
      }
  };

  const https = require('https');

  let req = https.request(options, (res) => {

        let body = [];
        res.on('data', function(chunk) {
            body.push(chunk);
        });

        res.on('end', function() {

            try {
                body = JSON.parse(Buffer.concat(body).toString());
                // how do i return the body?
            }
            catch(e) {
                console.error('HERE:',e.message)
                throw e;
            }

        });
  });

  req.on('error', (e) => {
        console.error('THERE:',e.message)
  });

  req.write(postData);
  req.end();

}

(async () => {

  try {
    data = {firstName: 'Donald', lastName: 'Duck'}
    const who = await async_it(data)
    console.info('INFO:',who)
  } 
  catch (error) {
    console.error('FATAL:',error)  
  }

})();

解决方案

核心问题是:async/await只是Promise的语法糖,无法直接处理回调式异步API。你之前的改写没有把https.request的异步逻辑包裹进Promise,导致async函数执行完同步代码就直接返回了一个空的Promise,自然拿不到响应体。

修正后的代码需要将整个https.request逻辑封装进Promise,再在async函数中返回这个Promise,这样await就能捕获到resolve的结果:

async_it = async (data) => {
  if (!data) {throw new Error('data is missing');}

  let postData = JSON.stringify(data);

  let options = {
      hostname: 'httpbin.org',
      port: 443,
      path: '/post',
      method: 'POST',
      headers: {
          'Content-Type': 'application/x-www-form-urlencoded',
          'Content-Length': postData.length
      }
  };

  const https = require('https');

  // 将请求逻辑封装进Promise
  return new Promise((resolve, reject) => {
    let req = https.request(options, (res) => {
      let body = [];
      res.on('data', function(chunk) {
          body.push(chunk);
      });

      res.on('end', function() {
          try {
              body = JSON.parse(Buffer.concat(body).toString());
              resolve(body); // 成功时传递响应体
          }
          catch(e) {
              console.error('HERE:',e.message);
              reject(e); // 解析失败时抛出错误
          }
      });
    });

    req.on('error', (e) => {
        console.error('THERE:',e.message);
        reject(e); // 请求错误时抛出错误
    });

    req.write(postData);
    req.end();
  });
}

(async () => {
  try {
    data = {firstName: 'Donald', lastName: 'Duck'}
    const who = await async_it(data);
    console.info('INFO:',who);
  } 
  catch (error) {
    console.error('FATAL:',error);  
  }
})();

关键说明

  • 对于Node.js中这类回调式的异步API(比如https.request、fs.readFile等),必须先通过new Promise进行Promise化,才能用async/await语法处理。
  • async函数内部通过return这个Promise,让外部的await可以等待异步操作完成,并获取resolve的结果;所有错误(请求错误、JSON解析错误)通过reject抛出,会被外层的try/catch捕获。
  • 你之前在回调中throw e不会被async函数的try/catch捕获,因为回调是异步执行的,不属于当前async函数的同步执行上下文,必须通过reject传递错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 11:31:01