Node.js在for循环中调用calback函数 [英] Node.js call calback function inside for loop

查看:65
本文介绍了Node.js在for循环中调用calback函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在中为循环调用一个函数,问题是在循环结束后调用该函数。

I am trying to call a function inside a for loop and the problem is that the function is called after the loop was finished.

以下面的例子为例,它打印到控制台:

here1

here1

here2

here2

Taking the below as an example, it prints to the console:
here1
here1
here2
here2

而不是

here1

here2

here1

here2

report.forEach(item => {
  item.runs.forEach(run => {
    waComplianceBusiness(req, run.id, (err, res) => {
      const compliance = res.data.overviews[0].compliance;
      var failureList = [];

      compliance.forEach((rule, index) => {
        console.log('here1');
        waRuleOverview(req, run.id, rule.id, (err, res) => {
          console.log('here2');
          // handle the response
        });
      });
    });
  });
});

我该如何解决这个问题?

How can I fix this?

如果我需要提供更多信息,请告诉我

Please let me know if I need to provide additional information

以下是完整代码:

export default (req, callback) => {
  const report = req.body.webAudits;

  if(report.length > 0) {
    report.forEach(item => {
      item.runs.forEach(run => {
        waComplianceBusiness(req, run.id, (err, res) => {
          const compliance = res.data.overviews[0].compliance;
          if(compliance) {
            var failureList = [];
            compliance.forEach((rule, index) => {
              if(rule.pagesFailed > 0) {
                waRuleOverview(req, run.id, rule.id, (err, res) => {
                  const failedConditions = res.data.failedConditions;
                  const ruleName = res.data.ruleName;

                  failedConditions.forEach((condition, failedIndex) => {
                    const request = {
                      itemId: condition.conditionResult.id,
                      itemType: condition.conditionResult.idType,
                      parentId: condition.conditionResult.parentId,
                      parentType: condition.conditionResult.parentType
                    }
                    const body = {
                      runId: run.id,
                      ruleId: rule.id,
                      payload: request
                    }

                    waConditionOverview(req, body, (err, res) => {
                      const description = res.data.description;
                      const conditionValues = res.data.conditionValues[0];
                      var actualValue = conditionValues.value;

                      if(actualValue == "") {
                        actualValue = 'empty';
                      }

                      if(description.idType == "variable") {
                        var failureObj = {
                          ruleName: ruleName,
                          expected: description.name + ' ' + description.matcher + ' ' + description.expected[0],
                          actual: description.name + ' ' + description.matcher + ' ' + actualValue
                        };
                      }
                      else if(description.idType == "tag") {
                        var failureObj = {
                          ruleName: ruleName,
                          expected: description.name + '\n' + description.matcher,
                          actual: actualValue
                        };
                      }
                      failureList.push(failureObj);
                    });
                  });
                });
              }
              if(key + 1 == compliance.length) {
                console.log(failureList);
              }
            });
          }
        });
      });
    });
  }
}

这些是回调函数:

export function waComplianceBusiness(req, runId, callback) {
  const apiToken = req.currentUser.apiToken;
  const payload = {
    'Authorization': 'api_key ' + apiToken
  }

  const options = {
    'method': 'get',
    'gzip': true,
    'headers': payload,
    'content-type': 'application/json',
    'json': true,
    'url': 'api_url'
  }

  request(options, (error, response, body) => {
    callback(null, body);
  });
}

export function waRuleOverview(req, runId, ruleId, callback) {
  const apiToken = req.currentUser.apiToken;
  const payload = {
    'Authorization': 'api_key ' + apiToken
  }

  const options = {
    'method': 'get',
    'gzip': true,
    'headers': payload,
    'content-type': 'application/json',
    'json': true,
    'url': 'api_url'
  }

  request(options, (error, response, body) => {
    callback(null, body);
  });
}

export function waConditionOverview(req, body, callback) {
  const apiToken = req.currentUser.apiToken;
  const payload = {
    'Authorization': 'api_key ' + apiToken
  }

  const options = {
    'method': 'post',
    'gzip': true,
    'headers': payload,
    'body': body.payload,
    'content-type': 'application/json',
    'json': true,
    'url': 'api_url'
  }

  request(options, (error, response, body) => {
    callback(null, body);
  });
}

我的目标是返回 failureList 合规性数组后的c $ c>数组

My goal is to return the failureList array after the loop over the compliance array is done

我发现了一个类似的问题这里但不确定这是否适用于我的情况而且我不知道我真的知道如何实现承诺

I found a similar question here but not sure if that would work in my case and I don't really know how to implement the promises

推荐答案

如果你想按顺序使用async.eachOfSeries

If you want to do it in sequence use async.eachOfSeries

   async.eachOfSeries(report, function(item, index, eachOfCallback1){

       async.eachOfSeries(item.runs, function(run, index, eachOfCallback2){

          waComplianceBusiness(req, run.id, (err, res) => {

              var failureList = [];
              async.eachOfSeries(compliance, function(rule, index, eachOfCallback3){

                 console.log('here1');
                 waRuleOverview(req, run.id, rule.id, (err, res) => {
                     console.log('here2');
                     return eachOfCallback3(err);
                 });

               }, function(err){
                 if(err)
                    return eachOfCallback2(err);
                 else return eachOfCallback2();
               });

           });
        }, function(err){
           if(err)
              return eachOfCallback1(err);
           else return eachOfCallback1();
        })
    }, function(err){
       // handle final response  
    })

如果您想优化流程,请查看async.parallel

If you want to optimise the process take a look at async.parallel

这篇关于Node.js在for循环中调用calback函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆