我正在解析一系列文件并发布到数据库。作为其中的一部分,我需要保存文件中的数据总数,以及成功记录插入数据库的计数。承诺不是等待将所有记录写入数据库。
我正在寻找parserResults方法将testResults返回给调用.reduce。它确实将其传回,但insertSuccess = 0.
我添加了一些控制台日志以查看它正在做什么,并且在递增的insertSuccess计数器递增之前,finalResult正在控制台上显示。
Console.log结果
In parseresults ui-results-11705.json
In parseresults ui-results-14981.json
In parseresults ui-results-14982.json
In parseresults ui-results-28274.json
In parseresults ui-results-368.json
finalResult = { insertSuccess: 0,
insertFailed: 0,
testPassedCount: 2,
testFailedCount: 3 }
insertSuccess 1
insertSuccess 2
insertSuccess 3
insertSuccess 4
insertSuccess 5
这是调用将解析文件的函数的代码
matches.reduce(function (p, val) {
return p.then(function () {
console.log('p', p);
return parser.parseResults(val);
});
}, Promise.resolve()).then(function (finalResult) {
console.log('finalResult = ', finalResult);
}, function (err) {
console.log('error in reduce', err);
});
这是被称为
的方法
protractorParser.prototype.parseResults = function (fileName) {
return new Promise((resolve, reject) => {
console.log('In parseresults', fileName);
var currentFile = './testing/results/' + fileName
json.readFile(currentFile, function (err, obj) {
if (err != null) {
console.log('error reading file', err);
reject(err);
} else {
resolve(obj);
}
});
}).then(function (obj) {
var results = [];
for (var suite in obj) {
var specs = obj[suite].specs;
for (let i = 0; i < specs.length; i++) {
const assert = specs[i];
const tcR = /TC[\d]+/;
const tc = assert.description.match(tcR);
let Passed = 1;
let Message = '';
let Stack = '';
if (assert.failedExpectations.length) {
const expectation = assert.failedExpectations[assert.failedExpectations.length - 1];
Passed = 0;
Message = expectation.message;
Stack = expectation.stack.split('\n')[1].trim();
testResults.testFailedCount++
} else {
testResults.testPassedCount++
}
if (tc != null) {
const time = moment().utcOffset(config.get('settings.timeOffset')).format('YYYY-MM-DDTHH:mm:ss');
const promise = utility.TestDataManager.insertAutomationResults(tc[0], assert.description, Passed, process.env.testBuild, 'P', Message, Stack, 0, time, '');
results.push(promise.then(() => {
testResults.insertSuccess++;
console.log('insertSuccess', testResults.insertSuccess);
},
err => { console.log('… failed', err); throw err; }
));
} else {
console.log('no test case found for test: ' + assert.description + ' -- skipping');
// I don't think you want to `throw err` here, right?
}
}
}
return (Promise.all(results), testResults);
});
};
我在代码中玩过几种不同的场景,似乎无法弄明白。任何帮助将不胜感激。 谢谢 恭
答案 0 :(得分:2)
parseResults()
未正确返回承诺,因此p.then()
循环内的.reduce()
不会等待任何内容。
改变这个:
return (Promise.all(results), testResults);
到此:
return Promise.all(results).then(() => testResults);
您使用的代码:return (Promise.all(results), testResults);
仅返回testResults
,而不是承诺。我认为你想要的是知道所有的承诺何时完成,然后使testResults
成为已解决的值。为此,您使用.then()
上的Promise.all()
,然后从testResults
处理程序返回.then()
。这将返回单个承诺,其解析值为testResults
。
仅供参考,您可能根本不需要这样做,因为testResults
似乎是一个更高的范围变量,您可以直接引用它。如果你愿意这样做,那么你只需改为:
return Promise.all(results);
然后,不要在最终finalResult
处理程序中使用.then()
,只需直接引用更高范围的testResults
变量即可。
仅供参考,一个更干净的实现可以传递一个对象,循环的每次迭代返回并传递给下一次迭代,因此根本没有引用更高范围的变量,一切都更自包含。然后,您将使用我向您展示的第一种类型的返回,但是您将返回传入的对象,而不是更高范围的对象。