我正在尝试有希望地进行分页。这是我的工作流程。
第 1 步:分页总页数为 50。网址将类似于 url?page=1
第 2 步:在每个页面中我将获得 50 个产品,我需要调用单独的 api。
唯一的条件是,在分页期间,只有第一页的 50 api 调用完成后才应调用第二页。获取所有 50 个页面后,它应该返回 promise 。
到目前为止我所拥有的是。
let promises = [];
paginate(50);
Promise.all(promises)
.catch(function(err) {
console.log('err',err);
})
.then(() => {
console.log('All Done!!!!!');
});
function paginate(loop){
promises.push(
axios(config)
.then(function (response) {
// Got 50 products
})
.catch(function (error) {
console.log('err',err);
})
)
在 Got 50 products
的地方,我仍然需要在 axios 中迭代 50 个产品。我不确定是否可以在 Promise 中做 Promise。
由于服务器无法承受所有突发负载,唯一的条件是只有在第一个(或调用前 50 个 api)之后才迭代第二个 50 个产品(或下一页的产品)。
编辑:
//这里我有 50 个产品 正如我所说,在每个页面上我将获得 50 个产品,我将为所有这 50 个产品调用另一个 api。我已经给出了下面的代码。
唯一的限制是首页响应,应该调用响应 50 的 api.. 就像 product?product=1
。接下来的 50 个应该仅在前 50 个 api 调用之后调用
for (let index = 0; index < response.length; index++) {
const element = response[index];
//Here call api for one item
axios(config)
.then(function (elemen t) {
// Here i have got 50 products
})
.catch(function (error) {
console.log('err',err);
})
}
最佳答案
您可能不是在寻找 Promise.all
(用于并行运行),而是递归:
fetchPages(0, 49)
.then(console.log);
function fetchPages(from, to, results = []) {
if (from <= to) {
return fetchPage(from)
.then(res => results.push(...res))
.then(() => fetchPages(from + 1, to, results)); // calls itself
} else {
return results;
}
}
function fetchPage(n) {
console.log(`Fetching page ${n}`);
// Here, you would return axios()...
// But just for this demo, I fake that:
const results = new Array(50).fill(null)
.map((_,i) => `Product ${i} from page ${n}`);
return new Promise(resolve => setTimeout(() => resolve(results), 100));
}
编辑
上面的代码解决了只需要一页一页地获取页面的问题。我们可以保持 fetchPages 函数不变。现在,由于每个页面都包含需要单独获取的产品,因此我们只需稍微编辑 fetchPage
即可。
有多种方法可以做到这一点。以下是一些:
解决方案 A:并行获取每个产品
如果服务器可以同时处理 50 个请求,您可以使用 Promise.all
:
function fetchPage(n) {
console.log(`Fetching page ${n}`);
return axios(`/page?page=${n}`)
.then(productIds => {
return Promise.all(productIds.map(fetchProduct));
});
}
function fetchProduct(id) {
return axios(`/product?product=${id}`);
}
解决方案 B:按顺序获取每个产品
如果服务器无法同时处理多个请求,您可以再次使用递归:
function fetchPage(n) {
console.log(`Fetching page ${n}`);
return axios(`/page?page=${n}`)
.then(fetchproducts);
}
function fetchProducts(productIds, results = []) {
if (productIds.length) {
const productId = productIds.shift();
return fetchProduct(productId)
.then(res => results.push(res))
.then(() => fetchProducts(productIds, results)); // calls itself
} else {
return results;
}
}
function fetchProduct(id) {
return axios(`/product?product=${id}`);
}
解决方案 C:一次获取产品 X 个请求
如果服务器可以处理立即发出的 X 请求,您可以使用类似 queue 的模块,这可以帮助您提高并发性:
const queue = require('queue'); // Don't forget to $ npm install queue
const MAX_CONCURRENT_CALLS = 4; // 4 calls max at any given time
function fetchPage(n) {
console.log(`Fetching page ${n}`);
return axios(`/page?page=${n}`)
.then(fetchproducts);
}
function fetchProducts(productIds) {
const q = queue();
q.concurrency = MAX_CONCURRENT_CALLS;
const results = [];
q.push(
...productIds.map(productId => () => {
return fetchProduct(productId)
.then(product => results.push(product));
})
);
return new Promise((resolve, reject) => {
q.start(function (err) {
if (err) return reject(err);
resolve(results);
});
});
}
function fetchProduct(id) {
return axios(`/product?product=${id}`);
}
关于javascript - 如何在 promise 中履行 promise ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63859466/