如何解决如何在诺言中做诺言
我正在尝试以承诺做分页。这是我的工作流程。
第1步::分页总数为50。网址类似于url?page=1
第2步::在每个页面中,我将获得50种产品,需要调用一个单独的api。
唯一的条件是,在分页过程中,仅当完成第一页的50个api调用时,才应调用第二页。提取全部50页后,它应返回承诺。
我到目前为止所拥有的。
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种产品。我不确定是否可以在诺言中作出诺言。
由于服务器不能承受所有突然的负载,因此唯一的条件是仅在第一个50个(或调用前50个api)之后才迭代第二个50个产品(或下一页的产品)。
编辑:
//在这里,我有50种产品 正如我所说,在每个页面上我将获得50种产品,我将为这50种产品调用另一个api。我已经给出了下面的代码。
仅首页响应具有约束,应调用响应50的api。就像product?product=1
一样。仅在前50个api被调用之后,才应调用下50个
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,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}`);
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。