我试图在for循环中调用一个函数,问题是该函数是在循环完成后调用的。
以下面的例子为例,它将打印到控制台:
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
});
});
});
});
});我怎么才能解决这个问题?
如果需要提供更多的信息,请告诉我。
以下是完整的代码:
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数组的循环之后返回compliance数组。
我发现了一个类似的问题,这里,但不确定这在我的情况下是否有效,我真的不知道如何实现这些承诺
发布于 2017-08-03 13:49:46
for循环依次执行作用域中的语句。但是它不等待函数调用完成,它继续使用下一个语句(即异步工作)。这就是为什么结果是这样的。您可以使用Promises或使用async模块使其同步工作。
由于不清楚您将在函数调用中执行什么以及您希望这些语句做什么,所以我无法提出其中任何一个。。asyn.each通常是使for循环同步执行的首选。当您希望等待函数完成执行,然后执行操作时,就会使用承诺。你可能想看看他们的文档
async.each
谢谢你,拉盖尔
发布于 2017-08-03 15:24:53
如果要按顺序执行,请使用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
https://stackoverflow.com/questions/45485626
复制相似问题