Javascript 使用Fetch API递归返回分页输出 总结

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

我想使用JavaScript的FetchAPI递归地将分页输出整理成一个数组。从承诺开始,我认为异步/等待函数更合适

企图 以下是我的方法:

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()中
。我这样写只是为了清楚地了解发生了什么。