Javascript 节点-发出axios请求,直到条件为真
我试图使用一个变量在Javascript 节点-发出axios请求,直到条件为真,javascript,node.js,axios,instagram,Javascript,Node.js,Axios,Instagram,我试图使用一个变量在while循环中调用一个方法。我的目标是获取所有图像,直到具有下一页变量为真。此参数在来自联机api的每个请求之后返回。不幸的是,代码没有按预期工作 类刮刀{ 构造函数(){} 问题(下){ rl.setPrompt(输入文本); rl.prompt(); 返回新承诺((解决、拒绝)=>{ 让我们回答; rl.on('行',(输入)=>{ 答案=输入; rl.close(); }); rl.on('关闭',()=>{ 决心(回答); }); }) } startFetch(用
while
循环中调用一个方法。我的目标是获取所有图像,直到具有下一页
变量为真。此参数在来自联机api的每个请求之后返回。不幸的是,代码没有按预期工作
类刮刀{
构造函数(){}
问题(下){
rl.setPrompt(输入文本);
rl.prompt();
返回新承诺((解决、拒绝)=>{
让我们回答;
rl.on('行',(输入)=>{
答案=输入;
rl.close();
});
rl.on('关闭',()=>{
决心(回答);
});
})
}
startFetch(用户名){
this.username=字符串(用户名);
返回新承诺((解决、拒绝)=>{
axios({
网址:`https://www.instagram.com/${this.usernamee}/?\uu a=1`
})。然后((响应)=>{
//response.data.graphql.user);
userId=response.data.graphql.user.id;
//totalMedia=response.data.graphql.user.edge\u owner\u to\u timeline\u media.count
if(response.data.graphql.user.edge\u owner\u to\u timeline\u media.page\u info.has\u next\u page){
currCursor=response.data.graphql.user.edge\u owner\u to\u timeline\u media.page\u info.end\u cursor;
}
has_next_page=response.data.graphql.user.edge_owner_to_timeline_media.page_info.has_next_page;
//让节点=response.data.graphql.user.edge\u owner\u to\u timeline\u media.edges.length;
response.data.graphql.user.edge\u owner\u to\u timeline\u media.edges.map((项目,索引)=>{
this.processLink(item.node.display\uURL,索引);
});
解决();
});
});
}
fetchNextPage(用户ID){
axios({
方法:“GET”,
baseURL:'https://www.instagram.com/graphql/query/',
参数:{
查询_散列:“42323D648861228307BE10013AD2DC44”,
变量:{
id:userId,
第一:“12”,
之后:currCursor
}
}
})。然后((响应)=>{
console.log(response.data.data.user.edge\u owner\u to\u timeline\u media.edges[0]。节点)
//totalMedia=response.data.data.user.edge\u owner\u to\u timeline\u media.count
if(response.data.data.user.edge\u owner\u to\u timeline\u media.page\u info.has\u next\u page){
currCursor=response.data.graphql.user.edge\u owner\u to\u timeline\u media.page\u info.end\u cursor;
}
});
}
processLink(imageURI,n){
让filename=path.format({dir:destinationPath,base:`${n}.jpg`});
让file=fs.createWriteStream(文件名);
https.get(imageURI,(res)=>{
res.pipe(文件);
});
}
}
const ig=新刮刀();
//参考网址:https://www.instagram.com/profile/?__a=1
//我觉得下一个代码部分有点混乱?
ig.question('Username:')。然后((profileURI)=>{
//从ig api获取第一个光标,如果has_next_page为true,则获取next page
ig.startFetch(profileURI)。然后(()=>{
//而会导致内存错误吗?
while(有下一页){
ig.fetchNextPage(userId);
}
});
});
我在node cli脚本中创建了一个简单的类。如何正确调用fetchNextPage()
直到定义的变量为true?我有一个内存错误
<--- Last few GCs --->
[38139:0x105002a00] 66288 ms: Scavenge 2026.7 (2071.0) -> 2022.1 (2072.7) MB, 21.9 / 0.0 ms (average mu = 0.711, current mu = 0.384) allocation failure
[38139:0x105002a00] 66329 ms: Scavenge 2028.3 (2072.7) -> 2023.5 (2074.0) MB, 15.0 / 0.0 ms (average mu = 0.711, current mu = 0.384) allocation failure
[38139:0x105002a00] 66375 ms: Scavenge 2029.7 (2074.0) -> 2024.9 (2091.2) MB, 10.8 / 0.0 ms (average mu = 0.711, current mu = 0.384) allocation failure
<--- Last few GCs --->
[38139:0x105002a00] 66288 ms: Scavenge 2026.7 (2071.0) -> 2022.1 (2072.7) MB, 21.9 / 0.0 ms (average mu = 0.711, current mu = 0.384) allocation failure
[38139:0x105002a00] 66329 ms: Scavenge 2028.3 (2072.7) -> 2023.5 (2074.0) MB, 15.0 / 0.0 ms (average mu = 0.711, current mu = 0.384) allocation failure
[38139:0x105002a00] 66375 ms: Scavenge 2029.7 (2074.0) -> 2024.9 (2091.2) MB, 10.8 / 0.0 ms (average mu = 0.711, current mu = 0.384) allocation failure
<--- Last few GCs --->
[38139:0x105002a00] 66288 ms: Scavenge 2026.7 (2071.0) -> 2022.1 (2072.7) MB, 21.9 / 0.0 ms (average mu = 0.711, current mu = 0.384) allocation failure
[38139:0x105002a00] 66329 ms: Scavenge 2028.3 (2072.7) -> 2023.5 (2074.0) MB, 15.0 / 0.0 ms (average mu = 0.711, current mu = 0.384) allocation failure
[38139:0x105002a00] 66375 ms: Scavenge 2029.7 (2074.0) -> 2024.9 (2091.2) MB, 10.8 / 0.0 ms (average mu = 0.711, current mu = 0.384) allocation failure
<--- JS stacktrace --->
<--- Last few GCs --->
[38139:0x105002a00] 66288 ms: Scavenge 2026.7 (2071.0) -> 2022.1 (2072.7) MB, 21.9 / 0.0 ms (average mu = 0.711, current mu = 0.384) allocation failure
[38139:0x105002a00] 66329 ms: Scavenge 2028.3 (2072.7) -> 2023.5 (2074.0) MB, 15.0 / 0.0 ms (average mu = 0.711, current mu = 0.384) allocation failure
[38139:0x105002a00] 66375 ms: Scavenge 2029.7 (2074.0) -> 2024.9 (2091.2) MB, 10.8 / 0.0 ms (average mu = 0.711, current mu = 0.384) allocation failure
<--- JS stacktrace --->
<--- JS stacktrace --->
FATAL ERROR: MarkCompactCollector: young object promotion failed Allocation failed - JavaScript heap out of memory
<--- JS stacktrace --->
FATAL ERROR: MarkCompactCollector: young object promotion failed Allocation failed - JavaScript heap out of memory
Segmentation fault: 11
这是经过修改的代码
#!/usr/bin/env node
const axios = require('axios');
const path = require('path');
const https = require('https');
const fs = require('fs');
const rl = require('readline').createInterface({
input: process.stdin,
output: process.stdout
});
const destinationPath = path.format({dir: __dirname, base: 'scraped-profiles'});
let collectedLinks = [];
class Scraper {
constructor() {}
question(inputText) {
rl.setPrompt(inputText);
rl.prompt();
return new Promise( (resolve, reject) => {
let answer;
rl.on('line', (input) => {
answer = input;
rl.close();
});
rl.on('close', () => {
resolve(answer);
});
})
}
startFetch(username) {
this.username = String(username);
return axios({
url: `https://www.instagram.com/${this.username}/?__a=1`
}).then( (response) => {
console.log(response.data.graphql);
this.user_id = response.data.graphql.user.id;
this.has_next_page = response.data.graphql.user.edge_owner_to_timeline_media.page_info.has_next_page;
response.data.graphql.user.edge_owner_to_timeline_media.edges.map( (item) => {
collectedLinks.push(item.node.display_url);
});
if( this.has_next_page ){
this.currCursor = response.data.graphql.user.edge_owner_to_timeline_media.page_info.end_cursor;
this.fetchNextPage();
} else {
console.log('Completed');
}
});
}
fetchNextPage() {
return axios({
method: 'GET',
baseURL: 'https://www.instagram.com/graphql/query/',
params: {
query_hash: '42323d64886122307be10013ad2dcc44',
variables: {
id: this.user_id,
first: "12",
after: this.currCursor
}
}
}).then( (response) => {
console.log(response.data.data)
if( typeof response.data.data !== 'undefined' ){
if( response.data.data.user.edge_owner_to_timeline_media.page_info.has_next_page ){
this.currCursor = response.data.data.user.edge_owner_to_timeline_media.page_info.end_cursor;
response.data.data.user.edge_owner_to_timeline_media.edges.map( (item) => {
collectedLinks.push(item.node.display_url);
});
return this.fetchNextPage();
}
}
});
}
processLink() {
collectedLinks.forEach( (link, i) => {
let filename = path.format({dir: destinationPath, base: `${i}.jpg`});
let file = fs.createWriteStream(filename);
https.get(link, (res) => {
res.pipe(file);
});
});
}
}
const ig = new Scraper();
// https://www.instagram.com/username/?__a=1
ig.question('Username: ').then( (answer) => {
return ig.startFetch(answer).then( () => {
return ig.fetchNextPage();
});
}).then( () => {
ig.processLink();
console.log('All done');
});
问题在于axios请求是异步的,
while
循环在发出请求时不会暂停。因此,您几乎有一个无限循环,并且可能会发出数百个请求
更好的方法是从axios中递归调用fetchNextPage()
,然后
直到满足具有下一页的条件。我想你有一个问题,想让它不是真的,但这是一个假设
为了简洁起见,使用了一些伪代码:
fetchNextPage(userId) {
// return the axios promise so it can create promise chain
return axios({
....
}).then( (response) => {
// store current data from this response
// decide what to do next
if(!nextPageConditionMet){
// return another axios promise for another page to current `then()`
return this.fetchNextPage(userId)
}else{
// finally return all the pages
return storedPageCollection
}
});
}
ig.question('Username: ').then((profileURI) => {
// keep returning promises to each `then()
return ig.startFetch(profileURI).then(() => {
//Remove while loop
// return promise that won't be resolved until the next page
// condition is met in recursive calls made inside the function
return ig.fetchNextPage(userId);
});
}).then((pageCollection) => {
// do something with the final pageCollection
// that was returned in final `then()` of `fetchNextPage()`
console.log('All done!')
}).catch(err => console.log('Ooops something failed in the chain', err))
的has_nex_页面
由ig api提供,因此这是条件。它将是真的或假的,直到它是真的,我需要获取网页的内容。如果这是使用设置的!“下一页”中的条件是否只有在为false时才会调用?!false
为true。我不明白,对不起。如果api在传递到If(!has\u next\u page)
时返回has\u next\u page:true
,它将求值为If(!true)
这意味着不正确。是否执行后续块?忘记代码>和反转执行块,如果它让您感到困惑,我将使用一个简单的if(has\u next\u page)
,因此只有在has\u next\u page的值为true时才会调用获取其他页面的方法
fetchNextPage(userId) {
// return the axios promise so it can create promise chain
return axios({
....
}).then( (response) => {
// store current data from this response
// decide what to do next
if(!nextPageConditionMet){
// return another axios promise for another page to current `then()`
return this.fetchNextPage(userId)
}else{
// finally return all the pages
return storedPageCollection
}
});
}
ig.question('Username: ').then((profileURI) => {
// keep returning promises to each `then()
return ig.startFetch(profileURI).then(() => {
//Remove while loop
// return promise that won't be resolved until the next page
// condition is met in recursive calls made inside the function
return ig.fetchNextPage(userId);
});
}).then((pageCollection) => {
// do something with the final pageCollection
// that was returned in final `then()` of `fetchNextPage()`
console.log('All done!')
}).catch(err => console.log('Ooops something failed in the chain', err))