我正在尝试访问一个api,我将不得不根据需要迭代的页号多次运行api调用,以下是我正在使用的代码以及如何获得所有推送的响应放入数组。
因为nodeJs是单线程的,所以它不等待api的响应。 我该如何解决这个问题并确保所有响应值都被压入数组
在for循环中,我想要具有api响应的所有值的最终数组。因此,我检查总页值和响应页号是否匹配,这意味着将是最后一页,并且将数组推到另一个函数,但是当我这样做时,它不具有所有值,因为nodejs不等待api响应。
const fs = require('fs');
var pepKey = 'asdfasdfasd';
var pepResponse;
var pepTimecards = [];
pep();
function pep(){
var options = {
headers: {
"content-type": "application/json",
},
agentOptions: {
pfx: fs.readFileSync('./certificate/asdfsdaf.p12'),
passphrase: 'asdasdsda'
}
};
request.get('https://source.asdfasdf.io/api/organisations/asdfasdf/timecard_keys?timecard_type=Flex',options, (err, res, body) => {
if (err) { return console.log(err); }
pepResponse = JSON.parse(body)
pepTimecards = pepResponse.data;
if(pepResponse.pages > 1){
for(let i=2;i<=pepResponse.pages;i++){
var url = 'https://source.`pepme`.io/api/organisations/sdfsadf/timecard_keys?timecard_type=Flex&page='+pageNo;
request.get(url,options, (err, res, body) => {
if (err) { return console.log(err); }
body = JSON.parse(body)
pepTimecards = pepTimecards.concat(body.data)
if(pepResponse.pages == body.page){
console.log(pepResponse.pages)
console.log(body.page +"body page")
console.log(pepTimecards)
}
});
}
}else{
}
});
}
答案 0 :(得分:0)
使用请求承诺库,该库提供请求库的承诺版本。然后,您可以在for
循环中使用async / await来序列化您的操作:
较新的答案,可以与OP的问题中的已编辑代码一起使用
const fs = require('fs');
const rp = require('request-promise');
const pepKey = 'asdfasdfasd';
pep().then(pepTimecards => {
// the timecard data is valid in here
console.log(pepTimecards);
}).catch(err => {
console.log(err);
});
async function pep() {
let timecards = [];
const options = {
headers: {
"content-type": "application/json",
},
agentOptions: {
pfx: fs.readFileSync('./certificate/asdfsdaf.p12'),
passphrase: 'asdasdsda'
},
json: true,
uri: 'https://source.asdfasdf.io/api/organisations/asdfasdf/timecard_keys?timecard_type=Flex'
};
let pepResponse = await rp(options);
timecards = pepResponse.data;
if (pepResponse.pages > 1) {
for (let i = 2; i <= pepResponse.pages; i++) {
options.uri = 'https://source.`pepme`.io/api/organisations/sdfsadf/timecard_keys?timecard_type=Flex&page='+pageNo;
let body = await rp(url, options);
// add body.data onto the existing array
timecards.push(...body.data);
}
} else {
}
console.log(pepResponse.pages)
console.log(timecards)
return timecards;
}
在OP编辑问题代码之前先回答
const rp = require('request-promise');
// I'm assuming this is some sort of method definition on a class, otherwise it needs the function keyword
async pageno(pageNo) {
for (let i=2;i<=pepResponse.pages;i++){
try {
options.uri = 'https://test/timecard_keys?timecard_type=asdas&page='+pageNo;
// let request-promise parse the json for you automatically
options.json = true;
let body = await rp(options);
pepTimecards = pepTimecards.concat(body.data)
if (pepResponse.pages == body.page){
console.log(pepResponse.pages)
console.log(body.page +"body page")
console.log(pepTimecards)
}
} catch(e) {
// decide what to do for error handling
// this will log and rethrow so the caller will get a rejected promise
console.log(e);
throw e;
}
}
// return some value here to be the resolved value of the returned promise
return pepTimecards;
}
在您的代码中,尚不清楚声明options
,pepTimecards
,pepResponse
变量的位置。可能应该在此处将它们声明为局部变量,或者将其传递给函数和/或从函数中返回。
修改摘要:
async
,以便我们可以使用await
。rp
变量中options.json = true
添加到让请求承诺库自动为我们解析JSON结果rp()
以仅使用选项结构(向其添加URL)await
中的任何错误,将其记录下来,然后重新抛出,这样pageno()
将返回一个承诺,如果出现错误则拒绝该行为(您可以自定义行为,错误(如果需要)您仍需要解决的问题: