我的nodejs脚本有问题

时间:2016-06-16 11:46:30

标签: javascript node.js request cheerio

你可以帮我提一下小费:D。这是我的代码:

const request = require('request');
const cheerio = require('cheerio');

function getUrls(url) {
    const baseUrl = 'https://unsplash.com';
    let urls = [];
    request(url, (err, res, body) => {
        if (!err && res.statusCode === 200) {
            const $ = cheerio.load(body, { normalizeWhitespace: false, xmlMode: false, decodeEntities: true });
            $('.photo.qa-photo a').each((i, e) => {
                const lnk = $(e).attr('href');
                if (lnk.indexOf('@') === -1 && lnk.indexOf('download') === -1) {
                    urls.push(baseUrl + lnk);
                }
            });
        }
    });
    return urls;
}

function getImages(arr) {
    let images = [];
    for (const url of arr) {
        request(url, (err, res, body) => {
            if (!err && res.statusCode === 200) {
                const $ = cheerio.load(body, { normalizeWhitespace: false, xmlMode: false, decodeEntities: true });
                $('script').each((i, e) => {
                    if (i === 4) {
                        let img = $(e).text();
                        img = img.substring(img.indexOf('full') + 7, img.indexOf('regular') - 3);
                        images.push(img);
                    }
                });
            } else {
                console.log(err, res.statusCode);
            }
        });
    }
    return images;
}

console.log(getImages(getUrls('https://unsplash.com/search?utf8=%E2%9C%93&keyword=life&button=')));

单独的函数运行良好,但是如果我想结合这两个函数,console.log首先显示一个空数组,然后函数完成工作,但我看不到返回的数组,为什么?对不起我的英语不好。 有了这个小程序,我想从unsplash.com获得20张图片的完整网址 Ty提前。

2 个答案:

答案 0 :(得分:0)

Javascript是一种异步语言。这里发生的是您的getImages函数不会等待您的getUrls函数完成。

您需要在getImages功能中使用回调或承诺,以便等待getUrls

Here关于回调的一些小教程

回调是Javascript中非常重要的概念,我强烈建议您了解它是如何工作的。它会让你的生活更轻松。同样适用于承诺。

以下是您的代码

的示例
const request = require('request');
const cheerio = require('cheerio');

// callback is the function to be called when this one finishes
function getUrls(url, callback) {
    const baseUrl = 'https://unsplash.com';
    let urls = [];
    request(url, (err, res, body) => {
        if (!err && res.statusCode === 200) {
            const $ = cheerio.load(body, { normalizeWhitespace: false, xmlMode: false, decodeEntities: true });
            $('.photo.qa-photo a').each((i, e) => {
                const lnk = $(e).attr('href');
                if (lnk.indexOf('@') === -1 && lnk.indexOf('download') === -1) {
                    urls.push(baseUrl + lnk);
                }
            });
        }
    });
    //Notice the call to callback.
    callback(urls);
}
function getImages(arr) {
    let images = [];
    for (const url of arr) {
        request(url, (err, res, body) => {
            if (!err && res.statusCode === 200) {
                const $ = cheerio.load(body, { normalizeWhitespace: false, xmlMode: false, decodeEntities: true });
                $('script').each((i, e) => {
                    if (i === 4) {
                        let img = $(e).text();
                        img = img.substring(img.indexOf('full') + 7, img.indexOf('regular') - 3);
                        images.push(img);
                    }
                });
            } else {
                console.log(err, res.statusCode);
            }
        });
    }
    return images;
}

console.log(getUrls('https://unsplash.com/search?utf8=%E2%9C%93&keyword=life&button=', function(urls){getImages(urls)}));

我还没有对它进行过测试但它应该工作还是足够接近。

答案 1 :(得分:0)

Bacause请求函数异步调用,因此父函数(getUrls,getImages)在数组填充之前返回。你必须使用回调。