0

Почему получаю в результате пустой список?

Промежуточные выводы дают заполненные объекты, но такое чувство, что где то создается временный объект (массив) в который и пушится значение, а переданный в параметрах не заполняется.

Код:

var needle = require('needle');
var cheerio = require('cheerio');

function scrap(src_arr, res_arr){
    for(word of src_arr){
        var url = "https://wooordhunt.ru/word/" + word;
        console.debug(url)

        needle.get(url, function(err, res){
            if (err) throw err;

            var $ = cheerio.load(res.body);
            res_arr.push({
                word: $("#wd_title>h1").text().toLowerCase(),
                transcription_us: $("#us_tr_sound>span").text(),
                transcription_uk: $("#uk_tr_sound>span").text(),
                translation: $(".t_inline_en").text(),
            });
        });
    }
}

var src_words = ["about", "add", "afternon", "again"]
var result = [];
scrap(src_words, result)
console.log(result.length);

Результат:

https://wooordhunt.ru/word/about
https://wooordhunt.ru/word/add
https://wooordhunt.ru/word/afternon
https://wooordhunt.ru/word/again
0
0xdb
  • 51,614
  • 1
    Потому что не возвращается ничего из функции. А в функции создаётся новый массив, я так понимаю. Не передавай сам массив, просто внутри функции его заполняй. Он же в функции виден. – Alex Sazonov Feb 19 '20 at 10:00
  • Стоп, а что я должен вернуть из функции? Я же просто в функции выполняю действия над переданным в параметре массивом. – Kirill Lipanov Feb 19 '20 at 10:05
  • @Denis640Kb Не, это да, но он хочет заполнить пустой массив, передав его в функцию. Хотя, кажется, массивы и объекты (что одно и то же) передаются по ссылке в функции. Но я не совсем понял как это работает. Я в фиддле сейчас попробовал. Точно то, что переданный массив в функции при сравнении говорит, что они одно и то же. Но я бы из функции обращался к массиву не в функции который объявлен. – Alex Sazonov Feb 19 '20 at 10:09
  • Попытался переделать вот как: Перед needle.get(...) объявил пустой объект. В needle.get(...) заполняю этот объект, и после этого разпечатываю его. Тадам! Объект пустой – Kirill Lipanov Feb 19 '20 at 10:12
  • @Denis640Kb Извини, совсем не понял твой комментарий) – Kirill Lipanov Feb 19 '20 at 10:17
  • Кстати, тестово уже попробовал заполнить массив в функции, передав его как параметр. Все ОК. – Kirill Lipanov Feb 19 '20 at 10:18
  • @KirillLipanov, Не помню, чтобы мы с Вами на "ты" переходили. 1. Проверьте выполнение needle.get Прописав после if (err) throw err; console.log(res);. 2.Проверьте получаемые данные console.log(res.body);. 3. Проверьте сам параметр, к примеру $("#wd_title>h1").text().toLowerCase(). – Denis640Kb Feb 19 '20 at 10:24
  • Я непосредственно в самом needle.get(...) распечатывал создаваемые объекты, она заполнены и корректны. Выносил создание объекта за needle.get(...), в needle.get(...) заполнял его, после needle.get(...) его выводил, там пусто. Создалось ощущение, что проблема с областью видемости переменных. – Kirill Lipanov Feb 19 '20 at 10:32
  • Как оказалось, все дело в асинхронности. Я выважу массив результато, до того как пришел сам результат. – Kirill Lipanov Feb 19 '20 at 10:56

1 Answers1

1
var needle = require('needle');
var cheerio = require('cheerio');
function a_get(url, res_arr){
    return new Promise(function(resolve, reject){
            needle.get(url, function(err, res){
            if (err) throw err;

            var $ = cheerio.load(res.body);
            resolve(res_arr.push({
                word: $("#wd_title>h1").text().toLowerCase(),
                transcription_us: $("#us_tr_sound>span").text(),
                transcription_uk: $("#uk_tr_sound>span").text(),
                translation: $(".t_inline_en").text(),
            }));
        });
    });
}

async function scrap(src_arr, res_arr){
    for(word of src_arr){
        var url = "https://wooordhunt.ru/word/" + word;
        console.debug(url)
        await a_get(url, res_arr);

    }
}

var src_words = ["about", "add", "afternon", "again"]
var result = [];
scrap(src_words, result).then(res => console.log(result.length));

Все дело в асинхронности. ТЫ выводишь длину массива до того, как выполнится get запрос. Промисы и async/await(по сути то же,что и промис, просто синтаксический сахар) помогли решить твою проблему