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

点点圈 提交于 2019-12-18 04:35:09

问题


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);
        });
    });
});

回答1:


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...');
      }
    });
  });
});



回答2:


you should be able to just pass done to your it function. then, after an async req is done, you would add line done() after your asserts. If there is an error, you would pass it to the done function like done(myError)

https://mochajs.org/#asynchronous-code for more info



来源:https://stackoverflow.com/questions/41470296/how-to-await-and-return-the-result-of-a-http-request-so-that-multiple-request

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!