【问题标题】:Fetch Http Response NodeJS获取 Http 响应 NodeJS
【发布时间】:2019-05-23 20:36:14
【问题描述】:

尝试在 NodeJS(nodeJs 的新手)中执行 AWS Lambda,我在其中发出 http 请求。在Lambda执行结束时,我希望返回http请求的响应码和响应消息。

发起http请求调用:

var executeRequest = function(request, callback) {

const req = https.request(request, (res) => {

  console.log('statusCode:', res.statusCode);
  console.log('headers:', res.headers);

  res.on('data', (d) => {
     process.stdout.write(d);
  });
  callback(res);
});

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

req.end(request.body);

};

Lambda 代码:

    exports.handler = (event, context, callback) => {

    // Formulate request 

    var result = executeRequest(request, function(response) {
         console.log("Response Code: ", response.statusCode);
         console.log("Response Message: ", response.statusMessage);
         // Successfully able to print the response above

        return response;
     });
     console.log("Result Response Code: ", result);
     console.log("Result Response Message: ", result);
     } 

我希望将 response.statusCode 和 response.statusMessage 作为 Lambda 的响应返回

return{
    statusCode: <the code>,
    body: <the message>,
};

但是,结果填充为未定义。如何提取所需的响应参数以便正确返回?

** 编辑:** 建议更改后的片段: 使用 Promise 的代码:

var executeRequest = function(request, callback) {

    return new Promise((resolve, reject) => {
        https.request(request, function(res) {
            if(res.statusCode==200 || res.statusCode==404) {
                resolve(res);
            }
            else {
                console.error(res);
                reject(res.statusCode);
            }
        }).end(request.body || '');
    });
};


exports.handler = (event, context, callback) => {

    // Formulate request 

    var value = executeRequest(request).then(function(result) {
  console.log("Result ", result);
  const response = { statusCode: 200, body: JSON.stringify('Hello from Lambda!') }; 
  return response;
 });

    console.log(value);
}

【问题讨论】:

  • 你能发布你得到的当前结果吗?
  • @Kannaiyan : Result Response Code: undefined Result Response Message: undefined
  • 使用 npm 包request 可能会更容易。
  • 将你的console.log行移到“result”函数中,否则它们将永远是未定义的(放在return response之前)

标签: node.js amazon-web-services aws-lambda


【解决方案1】:

问题是您的 executeRequest 是异步的,而您的 lambda 不知道这一点,所以它会立即返回。

不返回响应,而是将其作为第二个参数传递给callback(第一个是错误对象)

callback(null, response)

这部分被执行,不等待executeRequest响应,其余代码被执行

var result = executeRequest(request, function(response) {
     console.log("Response Code: ", response.statusCode);
     console.log("Response Message: ", response.statusMessage);
     // Successfully able to print the response above

    return response;
 });

所以在这一点上

console.log("Result Response Code: ", result);
console.log("Result Response Message: ", result);

result 还是空的。

所以你应该改为这样做。

var result = executeRequest(request, function(response) {
     console.log("Response Code: ", response.statusCode);
     console.log("Response Message: ", response.statusMessage);
     // Successfully able to print the response above

     callback(null, response);
 });

【讨论】:

  • 得到响应:ReferenceError:回调未定义
  • 你需要把上面的代码放到定义callbackexports.handler body中,我会更新代码sn -p
  • 可能会误解您的评论。 :( ...我已经编辑了我的问题以包含基于建议答案的代码以及正在打印的日志语句。
  • 异步是问题所在。尝试使用承诺。
  • @Hans-Eric Lippke:你有我可以参考的代码 sn-p 吗?我已经编辑了问题部分以包括使用 Promises。但是我在日志中得到INFO Promise { &lt;pending&gt; }
【解决方案2】:

试试这样的。

exports.handler = function( event, context, callback ) { 
 //this is to allow function to return as soon as result is shown
 context.callbackWaitsForEmptyEventLoop = false;
 var request = ...//I expect request is a predefined value or define the request here.

 executeRequest(request).then( function( result ) { 


  //keep all console log before return.
  console.log("Result ", result);

  const response = { statusCode: 200, body: JSON.stringify('Hello from Lambda!') }; 

  callback(null, response);
  return;
 });
}
function executeRequest(request){
   return new Promise( ( resolve, reject ) => {

    https.request(request, function(res) {

     if(res.statusCode==200 || res.statusCode==404) {
        resolve(res);
     }else {
        console.error(res);
        reject(res.statusCode);
        return;
     }
    }).end(request.body || '');
  });
}

【讨论】:

    【解决方案3】:

    将您的 Lambda 代码更改为以下内容,

    exports.handler = (event, context, callback) => {
    
        // Formulate request 
    
        var result = executeRequest(request, function(response) {
             console.log("Response Code: ", response.statusCode);
             console.log("Response Message: ", response.statusMessage);
             // Successfully able to print the response above
    
            callback(null, response);
         });
    
         } 
    

    希望对你有帮助。

    【讨论】:

    • 出现错误:ReferenceError:回调未定义
    • 您可能已经输入了它,而不是复制粘贴。可以看到是用箭头函数定义的。
    • @Kanniyan:可能误解了您的评论。 :( ...我已经编辑了我的问题以包含基于建议答案的代码以及正在打印的日志语句。
    • console.log("测试响应1:",结果); console.log("测试响应 2:", 回调);由于该函数不是同步调用。您不能在函数之外打印变量。你可以尝试使用 async 和 await。
    猜你喜欢
    • 2022-01-18
    • 2015-03-29
    • 2016-08-02
    • 1970-01-01
    • 2022-06-28
    • 2012-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多