Return 使用 Fetch 递归分页输出 API
Return paginated output recursively with Fetch API
总结
我想使用 JavaScript 的 Fetch API 递归地将分页输出整理成一个数组。从承诺开始,我认为 async/await 函数会更合适。
尝试
这是我的方法:
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 = /<([^>]+)>; 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) {
data = data.concat(fetchRequest(next_page));
} else {
console.log(data);
return data;
}
} catch (err) {
return console.error(err);
}
}
// Live demo endpoint to experiment with
fetchRequest("https://jsonplaceholder.cypress.io/posts?_page=9");
对于这个演示,它应该产生 2 个请求,这些请求产生一个包含 20 个对象的数组。虽然返回了数据,但我无法理解如何将它们整理成一个数组。任何指导将不胜感激。谢谢你的时间。
解决方案 #1
感谢@ankit-gupta:
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.test(response.headers.get("link"))) {
next_page = /<([^>]+)>; rel="next"/g.exec(response.headers.get("link"))[1];
}
// If another page exists, merge its output into the array recursively
if (next_page) {
data = data.concat(await fetchRequest(next_page));
}
return data;
} catch (err) {
return console.error(err);
}
}
fetchRequest("https://jsonplaceholder.cypress.io/posts?_page=9").then(data =>
console.log(data)
);
对于每一页,递归地进行后续调用并将它们连接到一个数组中。是否可以使用 Promises.all, similar to 并行链接这些调用?
附带说明一下,为什么 Whosebug 代码段在第二次获取时失败?
你需要把next_page
包裹在一个条件中,否则会导致最后一次调用时出现类型错误(因为/<([^>]+)>; 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);
});
总结
我想使用 JavaScript 的 Fetch API 递归地将分页输出整理成一个数组。从承诺开始,我认为 async/await 函数会更合适。
尝试
这是我的方法:
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 = /<([^>]+)>; 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) {
data = data.concat(fetchRequest(next_page));
} else {
console.log(data);
return data;
}
} catch (err) {
return console.error(err);
}
}
// Live demo endpoint to experiment with
fetchRequest("https://jsonplaceholder.cypress.io/posts?_page=9");
对于这个演示,它应该产生 2 个请求,这些请求产生一个包含 20 个对象的数组。虽然返回了数据,但我无法理解如何将它们整理成一个数组。任何指导将不胜感激。谢谢你的时间。
解决方案 #1
感谢@ankit-gupta:
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.test(response.headers.get("link"))) {
next_page = /<([^>]+)>; rel="next"/g.exec(response.headers.get("link"))[1];
}
// If another page exists, merge its output into the array recursively
if (next_page) {
data = data.concat(await fetchRequest(next_page));
}
return data;
} catch (err) {
return console.error(err);
}
}
fetchRequest("https://jsonplaceholder.cypress.io/posts?_page=9").then(data =>
console.log(data)
);
对于每一页,递归地进行后续调用并将它们连接到一个数组中。是否可以使用 Promises.all, similar to
附带说明一下,为什么 Whosebug 代码段在第二次获取时失败?
你需要把next_page
包裹在一个条件中,否则会导致最后一次调用时出现类型错误(因为/<([^>]+)>; 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);
});