保证在回国前不解决

时间:2018-02-15 01:18:12

标签: javascript arrays promise

我正在解析一系列文件并发布到数据库。作为其中的一部分,我需要保存文件中的数据总数,以及成功记录插入数据库的计数。承诺不是等待将所有记录写入数据库。

我正在寻找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);
    });
};

我在代码中玩过几种不同的场景,似乎无法弄明白。任何帮助将不胜感激。 谢谢 恭

1 个答案:

答案 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变量即可。

仅供参考,一个更干净的实现可以传递一个对象,循环的每次迭代返回并传递给下一次迭代,因此根本没有引用更高范围的变量,一切都更自包含。然后,您将使用我向您展示的第一种类型的返回,但是您将返回传入的对象,而不是更高范围的对象。