我使用promise.all来限制并发访问次数,但是promise.all()。then()不起作用,标志总是假的,为什么!!
function getPage(singeUrl) {
return new Promise((resolve,reject)=>{
superagent.get(singeUrl)
.set({'Content-Type': 'application/json',
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.96 Safari/537.36'})
.charset('utf8')
.end(function (err, sres) {
if (err) throw err;
utils.singleRequest(sres,db)
});
resolve('resolve=='+singeUrl)
})
}
let flag = true;
pages.forEach((item) => {
if(flag){
flag = false;
let promises = item.map(function (url) {
return getPage(url);
});
Promise.all(promises).then(res => {
flag = true;
})
}
})
答案 0 :(得分:0)
编辑:
问题是因为你循环遍历一个多维的promises数组,并且因为条件if (flag)
依赖于flag为true来执行pages.forEach()
中的任何代码,所以循环在之后停止执行任何代码第一次迭代。这是因为Promise.All()
是异步操作。当从pages[0]
创建的承诺已解决(也将flag
设置为true
)时,迭代已完成其第一个循环,但flag
仍设置为false
。
你可以通过展平promises的多维数组来解决这个问题,这样Promise.all()
将立即等待所有的promises,而不是迭代它们。
我对您的代码进行了一些更改以证明这一点:
let pages = [];
pages.push(['one', 'two']);
pages.push(['three', 'four']);
pages.push(['five', 'six']);
let getPage = function(singeUrl) {
return new Promise((resolve, reject)=>{
resolve('resolve=='+singeUrl)
if(!singleUrl) reject('No input');
});
}
let flag = true;
pages.forEach((item) => {
if(flag){
flag = false;
let promises = item.map(function (url) {
// You will notice in the output at the bottom, that
// only the array pages[0] have been executed by Promise.all()
console.log('url: ', url);
return getPage(url);
});
Promise.all(promises).then((res) => {
// The log statements below are executed last
console.log('flag1 in promise: ', flag);
flag = true;
console.log('flag2 in promise: ', flag);
});
}
});
// This statement executes before flag
// is set to true
console.log('final flag: ', flag);
输出:
url: one
url: two
final flag: false
flag1 in promise: false
flag2 in promise: true