咨询node里for循环调用异步方法的问题
发布于 7 年前 作者 a304885433 6290 次浏览 来自 问答
var fn = async (num) => {
    return new Promise((rosolve, reject) => {
        setTimeout(function () {
            console.log(num)
            throw new Error(num)
        }, 500);
    })
}

[1, 2, 3, 4, 5].forEach(async t => {
    await fn(t)
});

console.log('ok')

for循环内部调用异步方法,方法内部抛出异常后,要怎么改写下,才能阻止输出 ok 这是测试代码,实际场景有 钉钉接口,通过请求获取到部门列表,然后在去获取每个部门下的用户。

期望是: 每条数据处理过程中,如果发生异常,该http请求就被中止,并返回错误。

10 回复

用bluebird Promise.mapSeries

@Bingmang 感谢回复,我去看看

@Bingmang 谢谢 老哥的提醒 我也正好遇到类似的问题

forEach 是一个同步的迭代器,就算加了 async 也不会串行的异步进行。

正确的写法是采用 for/while 循环,结合 try-catch-finally。

async function task() {
    for (let i = 0; i < 10; i++) {
        try {
            await new Promise(rs => setTimeout(rs, 500));
            console.log(i);
            if (i === 5) {
                throw new Error(i);
            }
        }
        catch (err) {
            throw err; // 再拋
        }
    }
}

task()
    .then(res => {
        console.log('ok');
    })
    .catch(err => {
        console.error(err);
    })

/*
	0
	1
	2
	3
	4
	5
	Error: 5
*/

From PWA CNode

@Lizhooh 嗯,应该是forEach的问题,其次就是我的测试代码,应该需要调整下,按照你的指导,我调整成如下代码。

 let fn = (num) => {
        return new Promise((resolve, reject) => {
          setTimeout(function () {
            console.log(num);
            if (num >= 3) {
              //throw new Error('parse error') //throw直接会大致应用程序崩溃,而reject抛出异常,页面会正常提示异常信息
              reject('parse error')
            } else {
              resolve()
            }
          }, 500);
        })
      }

      for (let i = 0; i < 4; i++) {
        await fn(i);
      }

上述代码就是for的同步执行了。

//获取部门下人员详情
    return PromiseForEach(dd.deptlist, function (val) {
      return new Promise(function (resolve, reject) {
        https.get(`https://oapi.dingtalk.com/user/list?access_token=${dd.accessToken}&department_id=${val.id}`, function (response) {
          if (response.statusCode === 200) {
            var body = '';
            response.setEncoding('utf8');
            response.on('data', function (data) {
              body += data;
            }).on('end', function () {
              var result = JSON.parse(body);
              if (result && 0 === result.errcode) {
                resolve(result.userlist);//ok
              } else {
                reject(result);//err
              }
            })
          }
        })
      });
    })

其实使用for 循环就行,用foreach,map等不行,但是觉得for循环不够优雅,推荐使用bluebird,这是个人学习bluebird时写的一些笔记和demo,可以参考:https://github.com/MedusaLeee/bluebird-demo

附上for循环的写法

const arr = [1,2,3,4];
for(let i = 0; i < arr.length; i +=1){
	await fn(arr[i]);
}

for in 和 for of 也是可以的

递归啊 自豪地采用 CNodeJS ionic

for加async await

回到顶部