在nodejs中发出两个HTTP请求

我在Amazon Lambda上创build了一个函数。 我的情况是,我必须在两个不同的URL上同时发送两个HTTP请求。 所以我写了两个HTTP请求在我的代码与不同的URL。 问题是大多数情况下第一个HTTP请求没有被调用,第二个HTTP请求几乎一直在运行。 所以请帮我弄清楚这个问题。 这是我的代码

console.log('Loading function'); var aws = require('aws-sdk'); var http = require('http'); var s3 = new aws.S3({ apiVersion: '2006-03-01' }); exports.handler = function(event, context) { console.log('Received event:', JSON.stringify(event, null, 2)); // Get the object from the event and show its content type var bucket = event.Records[0].s3.bucket.name; var key = event.Records[0].s3.object.key; var params = { Bucket: bucket, Key: decodeURIComponent(key) }; s3.getObject(params, function(err, data) { if (err) { console.log("Error getting object " + key + " from bucket " + bucket + ". Make sure they exist and your bucket is in the same region as this function."); context.fail("Error getting file: " + err); } else { var userString = JSON.stringify(params); console.log(userString); var options = { hostname: 'example1.com', path: '/api/test1.cfm', method: 'POST', Port:'80', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'Content-Length': userString.length } }; console.log("Start"); var x = http.request(options,function(res){ console.log("Connected"); console.log('CONTENT TYPE:', data.ContentType); console.log("Start"); console.log("x"); context.succeed(data.ContentType); }); x.write(userString); x.end(); var optionsdev = { hostname: 'example2.com', path: '/api/test2.cfm', method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'Content-Length': userString.length } }; console.log("Start"); var y = http.request(optionsdev,function(res){ console.log("Connected"); console.log('CONTENT TYPE:', data.ContentType); console.log("Start"); console.log("y"); context.succeed(data.ContentType); }); y.write(userString); y.end(); } }); }; 

首先,如果您查看http.request()的node.js文档中的示例代码,您将得到一个callback,但是在该callback中,您传递了响应对象,并且该stream必须设置事件处理程序上。

以下是文档的基本结构:

 var req = http.request(options, function(res) { console.log('STATUS: ' + res.statusCode); console.log('HEADERS: ' + JSON.stringify(res.headers)); res.setEncoding('utf8'); res.on('data', function (chunk) { console.log('BODY: ' + chunk); }); res.on('end', function() { console.log('No more data in response.') }) }); req.on('error', function(e) { console.log('problem with request: ' + e.message); }); // write data to request body req.write(postData); req.end(); 

所以,当你在响应对象上收到“数据”和“结束”事件时,你必须处理响应。

对于大多数请求来说,这是不方便的,因为您必须累积响应,因为可以调用多个data事件。 我build议使用请求模块,因为它为你做了更多的工作。

然后,第二,如果你想要连续处理你的操作,你需要在第一个操作完成之前不要开始第二个操作。 有很多不同的方式来构build它,但是最类似于你已经拥有的结构的方法是在完成第一个请求的时候启动第二个请求。

以下是使用request()模块执行此操作的一种方法:

 var aws = require('aws-sdk'); var http = require('http'); var s3 = new aws.S3({ apiVersion: '2006-03-01' }); var request = require('request'); exports.handler = function(event, context) { console.log('Received event:', JSON.stringify(event, null, 2)); // Get the object from the event and show its content type var bucket = event.Records[0].s3.bucket.name; var key = event.Records[0].s3.object.key; var params = { Bucket: bucket, Key: decodeURIComponent(key) }; s3.getObject(params, function(err, data) { if (err) { console.log("Error getting object " + key + " from bucket " + bucket + ". Make sure they exist and your bucket is in the same region as this function."); context.fail("Error getting file: " + err); } else { var sendData = JSON.stringify(params); request.post('http://example1.com/api/test1.cfm', {form: sendData}, function(err, httpResponse, body) { if (err) { console.log("Error on first post"); } else { // do something with the response here console.log("first request = ", body); // context.succeed(...); // now launch the second request request.post('http://example2.com/api/test2.cfm', {form: sendData}, function(err, httpResponse, body) { if (err) { console.log("Error on second post"); } else { // do something with the response here console.log("second request = ", body) // context.succeed(...); // done with both requests here } }); } }); } }); };