Node.js导出导入失效:爬虫进度值无法同步问题求助
问题:爬虫进度变量导出后在主文件中始终显示0,更新不生效
我在Web爬虫的导出与app.js的导入环节遇到问题。从ticker函数中调用percentage函数时,无法通过返回值传递数据,希望更新roundedpercent变量并导出当前值,但app.js中始终输出0,即便爬虫已启动且进度不再为0%。
我的代码如下:
trader-german.js
async function starttrger(){ //... function ticker() { if (scraped == lastIndex) { percentage(scraped, lastIndex); //... } else { percentage(scraped, lastIndex); } } var percent = 0; var roundedpercent = 0; function percentage(scraped, lastIndex){ percent = scraped * 100 / lastIndex roundedpercent = Math.round(percent) console.log(roundedpercent) // 此处输出正确 } module.exports = { starttrger, roundedpercent }
app.js
const { starttrger,roundedpercent} = require('./trader-german'); app.post('/starttrger', async(req, res) => { await starttrger(); res.send({ message: 'Webscraper for trader-german started'}); }); function logProgress() { console.log(`current Progress: ${roundedpercent}%`); } setInterval(logProgress, 1000);
trader-german.js中的console.log能正确输出当前百分比,但app.js中每次都输出0,求解决方案。
问题原因
你导出的roundedpercent是原始数值类型变量,JavaScript中基本类型是值传递——app.js导入的只是初始值0的副本,trader-german.js后续对该变量的更新不会同步到副本上,所以始终显示0。
解决方案
方法一:用对象包裹进度变量
利用对象的引用传递特性,让主文件和爬虫文件共享同一个对象引用:
修改trader-german.js:
async function starttrger(){ //... function ticker() { if (scraped == lastIndex) { percentage(scraped, lastIndex); //... } else { percentage(scraped, lastIndex); } } // 用对象包裹进度变量 const progress = { roundedpercent: 0 }; function percentage(scraped, lastIndex){ const percent = scraped * 100 / lastIndex progress.roundedpercent = Math.round(percent) console.log(progress.roundedpercent) } module.exports = { starttrger, progress }
修改app.js:
const { starttrger, progress} = require('./trader-german'); app.post('/starttrger', async(req, res) => { await starttrger(); res.send({ message: 'Webscraper for trader-german started'}); }); function logProgress() { console.log(`current Progress: ${progress.roundedpercent}%`); } setInterval(logProgress, 1000);
方法二:提供获取进度的函数
通过函数调用实时获取最新的进度值:
修改trader-german.js:
async function starttrger(){ //... function ticker() { if (scraped == lastIndex) { percentage(scraped, lastIndex); //... } else { percentage(scraped, lastIndex); } } let roundedpercent = 0; function percentage(scraped, lastIndex){ const percent = scraped * 100 / lastIndex roundedpercent = Math.round(percent) console.log(roundedpercent) } // 新增获取进度的函数 function getProgress() { return roundedpercent; } module.exports = { starttrger, getProgress }
修改app.js:
const { starttrger, getProgress} = require('./trader-german'); app.post('/starttrger', async(req, res) => { await starttrger(); res.send({ message: 'Webscraper for trader-german started'}); }); function logProgress() { console.log(`current Progress: ${getProgress()}%`); } setInterval(logProgress, 1000);
方法三:用事件发射器主动通知进度(适合复杂场景)
无需轮询,进度更新时主动触发事件通知主文件:
修改trader-german.js:
const EventEmitter = require('events'); const progressEmitter = new EventEmitter(); async function starttrger(){ //... function ticker() { if (scraped == lastIndex) { const currentProgress = percentage(scraped, lastIndex); // 触发进度更新事件 progressEmitter.emit('progress-update', currentProgress); //... } else { const currentProgress = percentage(scraped, lastIndex); progressEmitter.emit('progress-update', currentProgress); } } function percentage(scraped, lastIndex){ const percent = scraped * 100 / lastIndex const roundedpercent = Math.round(percent) console.log(roundedpercent) return roundedpercent; } module.exports = { starttrger, progressEmitter }
修改app.js:
const { starttrger, progressEmitter} = require('./trader-german'); app.post('/starttrger', async(req, res) => { await starttrger(); res.send({ message: 'Webscraper for trader-german started'}); }); // 监听进度更新事件 progressEmitter.on('progress-update', (progress) => { console.log(`current Progress: ${progress}%`); });
内容的提问来源于stack exchange,提问作者Hannes Z
相关产品推荐
相关产品推荐

