How to execute synchronous HTTP requests in JavaScript

Viewed 7158

I need to execute unknown number of http requests in a node.js program, and it needs to happen synchronously. only when one get the response the next request will be execute. How can I implement that in JS?

I tried it synchronously with the requset package:

function HttpHandler(url){

  request(url, function (error, response, body) {
     ...
  })

}

HttpHandler("address-1")
HttpHandler("address-2")
...
HttpHandler("address-100")

And asynchronously with request-promise:

async function HttpHandler(url){

  const res = await request(url)
  ...

}

HttpHandler("address-1")
HttpHandler("address-2")
...
HttpHandler("address-100")

Non of them work. and as I said I can have unknown number of http request over the program, it depends on the end user.

Any ideas on to handle that?

1 Answers

Use the got() library, not the request() library because the request() library has been deprecated and does not support promises. Then, you can use async/await and a for loop to sequence your calls one after another.

const got = require('got');
let urls = [...];    // some array of urls

async function processUrls(list) {
    for (let url of urls) {
        await got(url);
    }
}

processUrls(urls).then(() => {
    console.log("all done");
}).catch(err => {
    console.log(err);
});

You are claiming some sort of dynamic list of URLs, but won't show how that works so you'll have to figure out that part of the logic yourself. I'd be happy to show how to solve that part, but you haven't given us any idea how that should work.


If you want a queue that you can regularly add items to, you can do something like this:

class sequencedQueue {
    // fn is a function to call on each item in the queue
    // if its asynchronous, it should return a promise
    constructor(fn) {
        this.queue = [];
        this.processing = false;
        this.fn = fn;
    }
    add(...items) {
        this.queue.push(...items);
        return this.run();
    }
    async run() {
        // if not already processing, start processing
        // because of await, this is not a blocking while loop
        while (!this.processing && this.queue.length) {
            try {
                this.processing = true;
                await this.fn(this.queue.shift());
            } catch (e) {
                // need to decide what to do upon error
                // this is currently coded to just log the error and
                // keep processing.  To end processing, throw an error here.
                console.log(e);
            } finally {
                this.processing = false;
            }
        }
    }
}
Related