Nodejs回调函数和返回值
Nodejs回调函数和返回值
现在我需要用Nodejs抓取一个网站上面的数据,数据可能有几千条,分几十页,而且每一页都是一次请求,现在我需要对外部提供一个接口,就是可以一次返回这几千条数据的接口。 问题是是获取页数之后循环请求,但是返回的数据在每次请求的回调函数里,我该怎么把这些回调函数里面的数据汇总到一起并返回给调用接口啊?
当然可以!在Node.js中处理异步操作时,回调函数是一个常见的模式。当你需要从多个异步请求中收集数据,并最终返回这些数据时,可以使用Promise或async/await来简化代码逻辑。这里我将通过一个具体的例子来说明如何实现这个功能。
假设我们需要从一个网站抓取多页数据,每一页都需要发送HTTP请求。我们将使用axios
库来进行HTTP请求,并使用Promise.all
来处理多个异步请求。
首先,确保你已经安装了axios
库:
npm install axios
接下来,我们编写一个简单的函数来抓取多页数据,并返回一个包含所有数据的数组。
const axios = require('axios');
// 定义一个函数来抓取单个页面的数据
function fetchDataFromPage(pageNumber) {
return axios.get(`https://example.com/api/data?page=${pageNumber}`)
.then(response => response.data)
.catch(error => {
console.error(`Error fetching data from page ${pageNumber}:`, error);
throw error;
});
}
// 主函数,用于抓取多页数据
async function fetchMultiplePages(pageCount) {
try {
// 创建一个空数组来存储所有页面的数据
const allData = [];
// 使用for循环来请求每个页面
for (let i = 1; i <= pageCount; i++) {
const data = await fetchDataFromPage(i);
allData.push(data);
}
// 返回所有抓取到的数据
return allData;
} catch (error) {
console.error('Error fetching multiple pages:', error);
throw error;
}
}
// 调用主函数
fetchMultiplePages(10)
.then(data => {
console.log('Fetched data:', data);
})
.catch(error => {
console.error('Failed to fetch data:', error);
});
在这个例子中,我们定义了一个fetchDataFromPage
函数来处理单个页面的数据抓取。然后我们使用fetchMultiplePages
函数来处理多个页面的数据抓取,并使用await
关键字等待每个异步请求完成。
最后,我们通过调用fetchMultiplePages
函数并传入页数(例如10),就可以一次性获取所有页面的数据,并将它们汇总在一起。
这样做的好处是代码更简洁、可读性更强,并且可以更容易地处理错误。希望这个示例对你有所帮助!
用 eventproxy
使用计数器. 你要分发多少个处理函数,就要对每一个完成的回调函数进行计数判断: function check () { nums–; if (nums === 0) { // do something. } }
每一个回调函数中都使用这个检测函数来进行逻辑监测,以回到下一个进程线 类似于交换机侦听 …(…, function (…) { … check(); });
比如我写的howdo吧,虽然简单,也是可以完成的
var howdow = new Howdo();
// 这是页数,可以顺序也可以是乱序
var pages = [0, 1, 2, 3, 4, …];
pages.forEach(function(page) {
// 分配任务
howdo.task(function(done) {
request(page, function(e, result) {
// 各种处理之后...,提交任务
done(e, result);
});
});
});
// 分页去查询,这些任务之间没有依赖关系
// 各个任务可以一起做
howdo.together(function(e, page0, page1, page2, page3, page4, …) {
// 只要其中1个任务出现错误,都会返回错误
if(e) return callback(e);
// 参数顺序和分配任务时的顺序一致
// 这里得到了所有的分页数据
// 然后再拼接返回即可
var data = [].concat.apply([], [].slice.call(arguments, 1));
callback(null, data);
});
你可以看一下 async 模块的 map方法 https://github.com/caolan/async#map
在Node.js中处理异步操作时,通常会使用回调函数来管理异步流程。对于你的情况,你需要从多个页面获取数据,并将这些数据汇总后返回。你可以使用async/await
结合Promise
来简化这一过程。
示例代码
假设你有一个函数fetchPageData(pageNum)
,它返回一个Promise,该Promise会在完成请求后解析为该页的数据。你可以使用以下代码来实现:
const fetch = require('node-fetch'); // 假设你使用的是node-fetch库
// 模拟一个函数,用于从指定页码获取数据
function fetchPageData(pageNum) {
return new Promise((resolve, reject) => {
fetch(`https://example.com/data?page=${pageNum}`)
.then(response => response.json())
.then(data => resolve(data))
.catch(error => reject(error));
});
}
// 主函数,用于获取所有页的数据
async function getAllData() {
const totalPageCount = 10; // 总页数
let allData = [];
for (let i = 1; i <= totalPageCount; i++) {
try {
const pageData = await fetchPageData(i);
allData = allData.concat(pageData); // 将当前页的数据合并到allData中
} catch (error) {
console.error(`Error fetching page ${i}:`, error);
}
}
return allData;
}
// 使用getAllData函数
getAllData().then(data => {
console.log("All data:", data);
}).catch(error => {
console.error("Error:", error);
});
解释
-
fetchPageData
函数:这是一个异步函数,模拟了从某个页面获取数据的过程。这里我们假设使用了node-fetch
库来进行HTTP请求。 -
getAllData
函数:这是一个异步函数,负责从所有页码中获取数据并将它们合并在一起。我们通过一个循环遍历所有页码,并使用await
关键字等待每个页面的数据获取完成。 -
concat
方法:用于将新获取的数据合并到allData
数组中。 -
错误处理:在循环中捕获任何可能发生的错误,确保程序不会因为某一页的数据获取失败而完全中断。
这样,你就可以通过getAllData()
函数一次性获取所有页面的数据,并将其作为最终结果返回。