【问题标题】:promise.all().then not workpromise.all().then 不起作用
【发布时间】:2018-01-07 16:30:05
【问题描述】:

我用promise.all来限制并发访问次数,但是promise.all().then()不行,flag总是false,为什么!!

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;
			})
		}
	})

【问题讨论】:

标签: node.js concurrency es6-promise


【解决方案1】:

编辑:

问题在于,因为您正在循环通过一个多维的承诺数组,并且因为条件 if (flag) 依赖于标志为真来执行 pages.forEach() 中的任何代码,所以循环在第一次迭代后停止执行任何代码。这是因为Promise.All() 是一个异步操作。当从pages[0] 创建的promise 已经解决(这也将flag 设置为true)时,迭代已经完成了它的第一个循环,但flag 仍然设置为false

您可以通过展平 promise 的多维数组来解决这个问题,这样Promise.all() 将立即等待所有的 promise,而不是遍历它们。

我对您的代码进行了一些更改以证明这一点:

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

【讨论】:

  • pages 确实是一个多维数组
  • 对不起,我误解了这个问题。我已经编辑了我的解决方案,希望对你有用。
猜你喜欢
  • 1970-01-01
  • 2018-10-11
  • 2016-01-09
  • 2017-08-28
  • 1970-01-01
  • 1970-01-01
  • 2020-09-18
  • 2020-09-04
  • 1970-01-01
相关资源
最近更新 更多