Совместное использование переменной области с jsdom и jquery в Node

Итак, я писал простой скребок для страниц с jsdom и jquery и столкнулся с проблемой, которую я не знаю, как решить.

Вот некоторый код, который работает (изменил URL):

var jsdom = require("jsdom");
var fs = require('fs');
var jquery = fs.readFileSync("./js/jquery-min.js").toString();

//There's two pages of product, here's page 1
jsdom.env({
        url: 'http://exampleshoppingpage.com',
        src: [ jquery ],
        done: function(error, window){
                var $ = window.$;
                $('.productlist .product .title a').each(function() {
                        console.log($(this).text());
                });
        } 
});

//And do the exact same thing for page 2
jsdom.env({
        url: 'http://exampleshoppingpage.com?page=2',
        src: [ jquery ],
        done: function(error, window){
                var $ = window.$;
                $('.productlist .product .title a').each(function() {
                        console.log($(this).text());
                });
        } 
});

Но то, что я действительно хотел бы сделать, это получить все эти продукты и отсортировать их, прежде чем распечатать их. Вот что я пытался:

var jsdom = require("jsdom");
var fs = require('fs');
var jquery = fs.readFileSync("./js/jquery-min.js").toString();
var products = [];


//There's two pages of product, here's page 1
jsdom.env({
        url: 'http://exampleshoppingpage.com',
        src: [ jquery ],
        done: function(error, window){
                var $ = window.$;
                products $('.productlist .product .title a').each(function() {
                        products.push($(this).text());
                });
        } 
});

//And do the exact same thing for page 2
jsdom.env({
        url: 'http://exampleshoppingpage.com?page=2',
        src: [ jquery ],
        done: function(error, window){
                var $ = window.$;
                $('.productlist .product .title a').each(function() {
                        products.push($(this).text());
                });
        } 
});

products = products.sort();
console.log (products.join("\n"));

Я получаю пустой массив. Я попробовал несколько других способов определить, просто ли я делал что-то глупое. Я предполагаю, что это как-то связано с тем, что jQuery в jsdom не делит область видимости с внешней частью программы?

1 ответ

Решение

Это тот случай, когда мы должны помнить, чтобы думать асинхронно. Ваша сфера в порядке, но вы пытаетесь сбросить products чтобы утешить, прежде чем он заполнен данными.

Также, Array.prototype.sort() работает с массивом напрямую. Он не возвращает массив.

var jsdom = require("jsdom");
var jquery = "http://code.jquery.com/jquery.js";

var products = [];

//  page 1
jsdom.env({
        url: 'http://news.ycombinator.com/',
        scripts: [ jquery ],
        done: function(error, window){
                var $ = window.$;
                $('td.title:not(:last) a').each(function() {
                        products.push( $(this).text() );
                });
                //      page 2
                jsdom.env({
                        url: 'https://news.ycombinator.com/news?p=2',
                        scripts: [ jquery ],
                        done: function(error, window){
                                var $ = window.$;
                                $('td.title:not(:last) a').each(function() {
                                        products.push( $(this).text() );

                                });
                                products.sort();
                                console.log( products );
                        }
                });
        }
});
Другие вопросы по тегам