You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js异步请求导致返回数组为空问题:如何等待请求完成后再返回结果?

解决Node.js中异步请求导致返回空数组的问题

你猜的没错,问题确实出在request的异步特性上!当你的getWeather函数执行到return arr这一行时,网络请求还在后台跑,根本没来得及把解析到的title塞进数组里,所以返回的自然是空数组。下面给你几种常用的解决办法:

方法1:使用回调函数(传统异步处理方式)

修改函数,让它接受一个回调参数,在请求完成并解析完数据后,调用这个回调把结果传出去:

module.exports = function getWeather(country, callback) {
    var arr = [];
    var pageToVisit = "https://www.timeanddate.com/weather/" + country;
    console.log("Visiting page " + pageToVisit);
    request(pageToVisit, function(error, response, body) {
        if (error) {
            console.log("Error: " + error);
            return callback(error, null); // 把错误传递给回调
        }
        console.log("Status code: " + response.statusCode);
        if (response.statusCode === 200) {
            var $ = cheerio.load(body);
            console.log("Page title: " + $('title').text());
            $('div.bk-focus__qlook').each(function(index) {
                var title = $(this).find('div.h2').text().trim();
                console.log('title: ' + title);
                arr.push(title);
            });
            callback(null, arr); // 请求成功,返回填充好的数组
        } else {
            callback(new Error(`请求失败,状态码:${response.statusCode}`), null);
        }
    });
}

// 调用示例
getWeather('china', function(err, weatherData) {
    if (err) {
        console.error(err);
        return;
    }
    console.log(weatherData); // 这里就能拿到完整的天气数据数组了
});

方法2:使用Promise封装(现代异步处理方式,支持async/await)

把异步请求封装成Promise,这样可以用async/await语法让代码看起来更像同步逻辑,可读性更好:

module.exports = function getWeather(country) {
    return new Promise((resolve, reject) => {
        var arr = [];
        var pageToVisit = "https://www.timeanddate.com/weather/" + country;
        console.log("Visiting page " + pageToVisit);
        request(pageToVisit, function(error, response, body) {
            if (error) {
                console.log("Error: " + error);
                return reject(error); // 抛出错误
            }
            console.log("Status code: " + response.statusCode);
            if (response.statusCode === 200) {
                var $ = cheerio.load(body);
                console.log("Page title: " + $('title').text());
                $('div.bk-focus__qlook').each(function(index) {
                    var title = $(this).find('div.h2').text().trim();
                    console.log('title: ' + title);
                    arr.push(title);
                });
                resolve(arr); // 返回成功的结果
            } else {
                reject(new Error(`请求失败,状态码:${response.statusCode}`));
            }
        });
    });
}

// 调用示例(使用async/await)
async function fetchWeather() {
    try {
        const weatherData = await getWeather('china');
        console.log(weatherData); // 拿到填充好的数组
    } catch (err) {
        console.error(err);
    }
}

fetchWeather();

额外建议:使用request-promise简化代码

如果不想自己手动封装Promise,可以直接使用request-promise(它是request的Promise化版本),代码会更简洁:

首先安装依赖:

npm install request-promise cheerio

然后修改代码:

const rp = require('request-promise');
const cheerio = require('cheerio');

module.exports = async function getWeather(country) {
    var arr = [];
    var pageToVisit = "https://www.timeanddate.com/weather/" + country;
    console.log("Visiting page " + pageToVisit);
    
    try {
        const body = await rp(pageToVisit);
        console.log("Status code: 200"); // rp在请求失败时会自动抛出错误
        const $ = cheerio.load(body);
        console.log("Page title: " + $('title').text());
        $('div.bk-focus__qlook').each(function(index) {
            var title = $(this).find('div.h2').text().trim();
            console.log('title: ' + title);
            arr.push(title);
        });
        return arr;
    } catch (error) {
        console.log("Error: " + error);
        throw error; // 将错误抛给调用者处理
    }
}

// 调用示例
async function fetchWeather() {
    try {
        const weatherData = await getWeather('china');
        console.log(weatherData);
    } catch (err) {
        console.error(err);
    }
}

fetchWeather();

内容的提问来源于stack exchange,提问作者Liad Ben moshe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 09:53:12