Javascript 使用Fetch API递归返回分页输出 总结
我想使用JavaScript的FetchAPI递归地将分页输出整理成一个数组。从承诺开始,我认为异步/等待函数更合适 企图 以下是我的方法:Javascript 使用Fetch API递归返回分页输出 总结,javascript,node.js,recursion,pagination,fetch-api,Javascript,Node.js,Recursion,Pagination,Fetch Api,我想使用JavaScript的FetchAPI递归地将分页输出整理成一个数组。从承诺开始,我认为异步/等待函数更合适 企图 以下是我的方法: global.fetch=require(“节点提取”); 异步函数fetchRequest(url){ 试一试{ //获取请求并将其解析为JSON const response=等待获取(url); 让data=wait response.json(); //提取响应的“下一个”关系链接头的url 让next_page=/]+>;rel=“next”/g
global.fetch=require(“节点提取”);
异步函数fetchRequest(url){
试一试{
//获取请求并将其解析为JSON
const response=等待获取(url);
让data=wait response.json();
//提取响应的“下一个”关系链接头的url
让next_page=/]+>;rel=“next”/g.exec(response.headers.get(“link”))[1];
//如果存在另一个页面,请将其合并到数组中
//否则返回分页输出的完整数组
如果(下一页){
data=data.concat(fetchRequest(下一页));
}否则{
控制台日志(数据);
返回数据;
}
}捕捉(错误){
返回控制台。错误(err);
}
}
//要使用的实时演示端点
获取请求(“https://jsonplaceholder.cypress.io/posts?_page=9");
对于这个演示,它将产生2个请求,这些请求将生成一个包含20个对象的数组。虽然返回了数据,但我不知道如何将其整理成一个数组。任何指导都将不胜感激。谢谢你抽出时间
解决方案#1
感谢@ankit gupta:
异步函数fetchRequest(url){
试一试{
//获取请求并将其解析为JSON
const response=等待获取(url);
让data=wait response.json();
//提取响应的“下一个”关系链接头的url
让我们下一页;
if(/]+>;rel=“next”/g.test(response.headers.get(“link”)){
next_page=/]+>;rel=“next”/g.exec(response.headers.get(“link”))[1];
}
//如果存在另一个页面,则递归地将其输出合并到数组中
如果(下一页){
data=data.concat(等待获取请求(下一页));
}
返回数据;
}捕捉(错误){
返回控制台。错误(err);
}
}
获取请求(“https://jsonplaceholder.cypress.io/posts?_page=9)然后(数据=>
console.log(数据)
);您需要将
下一页
包装在一个条件中,否则将导致上次调用时的类型错误(因为/]+)>;rel=“next”/g.exec(response.headers.get(“link”)
将为空)
在确定数据之前,您需要承诺得到解决
对代码进行一些小的更改可以得到正确的输出:
global.fetch = require("node-fetch");
async function fetchRequest(url) {
try {
// Fetch request and parse as JSON
const response = await fetch(url);
let data = await response.json();
// Extract the url of the response's "next" relational Link header
let next_page;
if(/<([^>]+)>; rel="next"/g.exec(response.headers.get("link")))
next_page = /<([^>]+)>; rel="next"/g.exec(response.headers.get("link"))[1];
// If another page exists, merge it into the array
// Else return the complete array of paginated output
if (next_page) {
let temp_data = await fetchRequest(next_page);
data = data.concat(temp_data);
}
return data;
} catch (err) {
return console.error(err);
}
}
// Live, demo endpoint to experiment
fetchRequest("https://jsonplaceholder.cypress.io/posts?_page=9").then(data => {
console.log(data);
});
global.fetch=require(“节点提取”);
异步函数fetchRequest(url){
试一试{
//获取请求并将其解析为JSON
const response=等待获取(url);
让data=wait response.json();
//提取响应的“下一个”关系链接头的url
让我们下一页;
if(/]+>;rel=“next”/g.exec(response.headers.get(“link”))
next_page=/]+>;rel=“next”/g.exec(response.headers.get(“link”))[1];
//如果存在另一个页面,请将其合并到数组中
//否则返回分页输出的完整数组
如果(下一页){
让临时数据=等待获取请求(下一页);
data=data.concat(温度数据);
}
返回数据;
}捕捉(错误){
返回控制台。错误(err);
}
}
//现场,演示端点到实验
获取请求(“https://jsonplaceholder.cypress.io/posts?_page=9)然后(数据=>{
控制台日志(数据);
});
感谢您如此详细的回复,我非常感谢!与其在条件和逻辑中重复RegExp.exec
,不如在条件中使用RegExp.test
?建议通过将fetchRequest()
调用直接移动到data.concat()
中来绕过temp\u data
?你认为这个剧本的结构如何;可以改进吗?可以并行链接调用吗?对于并行链接调用,您需要删除从响应头获取下一个链接的依赖关系。您是否需要依赖每个响应的next
关系链接?我的意思是如果你知道起点是https://jsonplaceholder.cypress.io/posts?_page=8
结束点是https://jsonplaceholder.cypress.io/posts?_page=10
,您可以自己创建中间链接,对吗?是的,您可以将fetchRequest()直接移动到data.concat()中
。我这样写只是为了清楚地了解发生了什么。