Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to await and return the result of a http.request(), so that multiple requests run serially?

Assume there is a function doRequest(options), which is supposed to perform an HTTP request and uses http.request() for that.

If doRequest() is called in a loop, I want that the next request is made after the previous finished (serial execution, one after another). In order to not mess with callbacks and Promises, I want to use the async/await pattern (transpiled with Babel.js to run with Node 6+).

However, it is unclear to me, how to wait for the response object for further processing and how to return it as result of doRequest():

var doRequest = async function (options) {      var req = await http.request(options);      // do we need "await" here somehow?     req.on('response', res => {         console.log('response received');         return res.statusCode;     });     req.end(); // make the request, returns just a boolean      // return some result here?! }; 

If I run my current code using mocha using various options for the HTTP requests, all of the requests are made simultaneously it seems. They all fail, probably because doRequest() does not actually return anything:

describe('Requests', function() {     var t = [ /* request options */ ];     t.forEach(function(options) {         it('should return 200: ' + options.path, () => {             chai.assert.equal(doRequest(options), 200);         });     }); }); 
like image 714
CodeManX Avatar asked Jan 04 '17 17:01

CodeManX


1 Answers

async/await work with promises. They will only work if the async function your are awaiting returns a Promise.

To solve your problem, you can either use a library like request-promise or return a promise from your doRequest function.

Here is a solution using the latter.

function doRequest(options) {   return new Promise ((resolve, reject) => {     let req = http.request(options);      req.on('response', res => {       resolve(res);     });      req.on('error', err => {       reject(err);     });   });  }  describe('Requests', function() {   var t = [ /* request options */ ];   t.forEach(function(options) {     it('should return 200: ' + options.path, async function () {       try {         let res = await doRequest(options);         chai.assert.equal(res.statusCode, 200);       } catch (err) {         console.log('some error occurred...');       }     });   }); }); 
like image 179
mkhanoyan Avatar answered Sep 22 '22 04:09

mkhanoyan