Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 9224533
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 18, 20262026-06-18T04:20:45+00:00 2026-06-18T04:20:45+00:00

I am making anywhere between 1 to 10 web requests using jsdom (web-scraping library

  • 0

I am making anywhere between 1 to 10 web requests using jsdom (web-scraping library for Node.js). It goes something like this:

app.get('/results', function(req, res) {

jsdom.env(
  "http://website1.com",
  ["http://code.jquery.com/jquery.js"],
  function (errors, window) {
    // scrape website #1
  }
);

jsdom.env(
  "http://website2.com",
  ["http://code.jquery.com/jquery.js"],
  function (errors, window) {
    // scrape website #2
  }
);

jsdom.env(
  "http://website3.com",
  ["http://code.jquery.com/jquery.js"],
  function (errors, window) {
    // scrape website #3
  }
);
}

res.render('results', { items: items });
}

How do I run res.render() ONLY after all jsdom requests have been completed and after I have gathered all the information that I need? In a synchronous world this obviously would not be a problem, but since javascript is asynchronous, res.render() will be run before any of jsdom callbacks are finished.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-18T04:20:47+00:00Added an answer on June 18, 2026 at 4:20 am

    Naive solution

    The “naive” solution you could employ for a small number of scrapes is to nest everything (start each scrape in the callback of the last scrape, the last callback contains the render method.)

    scrape
      cb: scrape
         cb: scrape
            cb: render all results
    

    That becomes tedious and illegible, of course. (And everything runs in series, not parallel, which won’t be very fast.)

    Better solution

    The better solution would be to write a function to count the number of returned results and calls render when all have returned. Here is one implementation:

    function parallel_cb(total, finalCallback) {
        var done = 0;
        var results = [];
        return function(result) {
            done += 1;
            results.push(result);
            if (total == done) finalCallback(results);
        }
    }
    

    To use it in your example:

    app.get('/results', function(req, res) {
        var myCallback = parallel_cb(
            sitesToScrape.count, // or 3 in this case
            function(items) {res.render('results', { items: items })});
    
        jsdom.env(
          "http://nodejs.org/dist/",
          ["http://code.jquery.com/jquery.js"],
          function (errors, window) {
            // do some scraping
            myCallback(result_from_scrape);
          }
        );
    
        jsdom.env(
          "http://nodejs.org/dist/",
          ["http://code.jquery.com/jquery.js"],
          function (errors, window) {
            // more scraping
            myCallback(result_from_scrape);
          }
        );
    
        jsdom.env(
          "http://nodejs.org/dist/",
          ["http://code.jquery.com/jquery.js"],
          function (errors, window) {
            // even more scraping
            myCallback(result_from_scrape);
          }
        );
    });
    

    The best solution

    Instead of writing your own, you should really learn to use an existing parallel / async library as suggested by @almypal in the comment to your question.

    With async you could do something much neater as described in the docs: https://github.com/caolan/async#parallel

    Or if all your scrapes actually look for the same elements in the resulting pages, you could even do a parallel map over an array of URLs to scrape: https://github.com/caolan/async#maparr-iterator-callback

    Each of your scrapes can use the callback function provided by async’s parallel method, to return the results of its scrape. The final [optional] callback will contain your call to render with all the items.

    EDIT: The example you asked for

    This is your code, directly translated to the async library:

    var async = require("async");
    
    app.get('/results', function(req, res) {
        async.parallel( // the first argument is an array of functions
          [
            // this cb (callback) is what you use to let the async
            // function know that you're done, and give it your result
            function (cb) { 
              jsdom.env(
                "http://nodejs.org/dist/",
                ["http://code.jquery.com/jquery.js"],
                function (errors, window) {
                  // do some scraping      
    
                  // async's callback expects an error for the first
                  // param and the result as the second param
                  cb(null, result_from_scrape); //No error
                }
              );
            },
            function (cb) { 
              jsdom.env(
                "http://nodejs.org/dist/",
                ["http://code.jquery.com/jquery.js"],
                function (errors, window) {
                  // more scraping
                  cb(null, result_from_scrape);
                }
              );
            },
            function (cb) { 
              jsdom.env(
                "http://nodejs.org/dist/",
                ["http://code.jquery.com/jquery.js"],
                function (errors, window) {
                  // even more scraping
                  cb(null, result_from_scrape);
                }
              );
            }
          ],
          // This is the "optional callback". We need it to render.
          function (err, results) {
            // If any of the parallel calls returned an error instead
            // of null, it's now in the err variable.
            if (err) res.render('error_template', {error: err});
            else res.render('results', { items: results });
          });
    });
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Im making a flash app that will capture video from the users web-cam, show
I am making a simple slideshow view within my app. I'd like to link
Making a new site but something is happening to it in IE8. The social
Making a new site but something is happening to it in IE. I've purchased
Making my first steps in RIA Services (VS2010Beta2) and i encountered this problem: created
This question is about making an architectural choice prior to delving into the details
I'm making a little application for taking notes. So when I type 'note' anywhere
I am making a site, using only PHP as back-end (no framework), which should
Is thread local storage used anywhere else other than making global and static variables
This is a question on making custom fields in Django. I'm making a field

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.