访问请求 cheerios 函数之外的变量
Access variable outside request cheerio's fucntion
我在 cheerio 库的请求函数之外访问我的变量时遇到问题。
为了更好地理解,这里简化了我的代码:
var fullDragonInfo = {};
dragonsInfo.forEach(dragon => {
request(`url=${dragon.name}`, function (error, response, html) {
if (!error && response.statusCode == 200) {
var $ = cheerio.load(html);
$('tr').each(function (i) {
let childrenElement = $(this).children('td').children('font');
breedingList.push({
'parent_1': {
'name': childrenElement.eq(0).text(),
'color': childrenElement.eq(0).attr('color')
},
'parent_2': {
'name': childrenElement.eq(1).text(),
'color': childrenElement.eq(1).attr('color')
},
'Tokens': childrenElement.last().text()
});
});
Object.assign(fullDragonInfo, {
[dragon.name]: {
'type': dragon.type,
'tier': dragon.tier,
'class': dragon.class,
'breedable_level': dragon.breedable_level,
'breeds_combination': breedingList
}
});
}
});
});
fs.writeFile("finalData.json", JSON.stringify(fullDragonInfo));
所以我的输出文件 finalData.json
显示的是一个空对象。但是如果我在回调函数中做一个控制台日志,数据就在这里。
所以我认为问题是我无法在回调之外访问我的变量,但我不知道如何才能做到这一点。
由于请求是异步发生的,但您是同步写入文件的,因此它是在您的任何请求返回之前写入的。在写入文件之前,您需要等待您的请求完成。
如果你可以使用 promises,那可能会更好。但是只计算您的请求将减少对代码的修改,就像现在一样:
var fullDragonInfo = {};
var callbackCount = 0;
dragonsInfo.forEach(dragon => {
callbackCount++;
request(`url=${dragon.name}`, function (error, response, html) {
callbackCount--;
if (!error && response.statusCode == 200) {
var $ = cheerio.load(html);
$('tr').each(function (i) {
let childrenElement = $(this).children('td').children('font');
breedingList.push({
'parent_1': {
'name': childrenElement.eq(0).text(),
'color': childrenElement.eq(0).attr('color')
},
'parent_2': {
'name': childrenElement.eq(1).text(),
'color': childrenElement.eq(1).attr('color')
},
'Tokens': childrenElement.last().text()
});
});
Object.assign(fullDragonInfo, {
[dragon.name]: {
'type': dragon.type,
'tier': dragon.tier,
'class': dragon.class,
'breedable_level': dragon.breedable_level,
'breeds_combination': breedingList
}
});
}
if (callbackCount === 0) {
fs.writeFile("finalData.json", JSON.stringify(fullDragonInfo));
}
});
});
通过计算您发出的每个请求,然后在每次收到响应时删除一个计数,您将知道如果计数再次为零,则所有请求都必须完成。所以在每个请求结束时,我们检查它是否是最后一个完成的,如果是,将您的数据写入文件是安全的。
我在 cheerio 库的请求函数之外访问我的变量时遇到问题。
为了更好地理解,这里简化了我的代码:
var fullDragonInfo = {};
dragonsInfo.forEach(dragon => {
request(`url=${dragon.name}`, function (error, response, html) {
if (!error && response.statusCode == 200) {
var $ = cheerio.load(html);
$('tr').each(function (i) {
let childrenElement = $(this).children('td').children('font');
breedingList.push({
'parent_1': {
'name': childrenElement.eq(0).text(),
'color': childrenElement.eq(0).attr('color')
},
'parent_2': {
'name': childrenElement.eq(1).text(),
'color': childrenElement.eq(1).attr('color')
},
'Tokens': childrenElement.last().text()
});
});
Object.assign(fullDragonInfo, {
[dragon.name]: {
'type': dragon.type,
'tier': dragon.tier,
'class': dragon.class,
'breedable_level': dragon.breedable_level,
'breeds_combination': breedingList
}
});
}
});
});
fs.writeFile("finalData.json", JSON.stringify(fullDragonInfo));
所以我的输出文件 finalData.json
显示的是一个空对象。但是如果我在回调函数中做一个控制台日志,数据就在这里。
所以我认为问题是我无法在回调之外访问我的变量,但我不知道如何才能做到这一点。
由于请求是异步发生的,但您是同步写入文件的,因此它是在您的任何请求返回之前写入的。在写入文件之前,您需要等待您的请求完成。
如果你可以使用 promises,那可能会更好。但是只计算您的请求将减少对代码的修改,就像现在一样:
var fullDragonInfo = {};
var callbackCount = 0;
dragonsInfo.forEach(dragon => {
callbackCount++;
request(`url=${dragon.name}`, function (error, response, html) {
callbackCount--;
if (!error && response.statusCode == 200) {
var $ = cheerio.load(html);
$('tr').each(function (i) {
let childrenElement = $(this).children('td').children('font');
breedingList.push({
'parent_1': {
'name': childrenElement.eq(0).text(),
'color': childrenElement.eq(0).attr('color')
},
'parent_2': {
'name': childrenElement.eq(1).text(),
'color': childrenElement.eq(1).attr('color')
},
'Tokens': childrenElement.last().text()
});
});
Object.assign(fullDragonInfo, {
[dragon.name]: {
'type': dragon.type,
'tier': dragon.tier,
'class': dragon.class,
'breedable_level': dragon.breedable_level,
'breeds_combination': breedingList
}
});
}
if (callbackCount === 0) {
fs.writeFile("finalData.json", JSON.stringify(fullDragonInfo));
}
});
});
通过计算您发出的每个请求,然后在每次收到响应时删除一个计数,您将知道如果计数再次为零,则所有请求都必须完成。所以在每个请求结束时,我们检查它是否是最后一个完成的,如果是,将您的数据写入文件是安全的。