簡體   English   中英

承諾退貨前不解決

[英]promise not resolving before return

我正在解析文件數組並將其發布到數據庫。 作為其中的一部分,我需要將文件中的數據總計保留下來,並將成功記錄插入數據庫中的次數保留下來。 承諾不等待所有記錄都寫入數據庫。

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

我在代碼中使用了幾種不同的場景,似乎無法弄清楚。 任何幫助將不勝感激。 謝謝克里斯汀

parseResults()未正確返回承諾,因此p.then() .reduce()循環內的p.then()不會等待任何東西。

更改此:

return (Promise.all(results), testResults);

對此:

return Promise.all(results).then(() => testResults);

您正在使用的代碼: return (Promise.all(results), testResults); 只返回testResults ,而不是諾言。 我想您想要知道的是何時完成所有承諾,然后將testResults作為已解決的值。 為此,請在Promise.all() .then()上使用Promise.all() ,然后從該testResults .then()處理程序返回testResults 那將返回一個單獨的promise,其解析值為testResults

僅供參考,您可能根本不需要這樣做,因為testResults似乎是可以直接引用的更高范圍的變量。 如果您願意這樣做,則只需更改為:

return Promise.all(results);

而且,則不要使用finalResult在最后.then()處理程序,只是指高范圍的testResults直接變量。


僅供參考,對此的更清潔的實現可以傳入一個對象,該對象的每次循環迭代都返回並傳遞到下一個迭代,因此根本沒有引用更高范圍的變量,並且所有內容都更加獨立。 然后,您將使用我向您展示的第一種返回類型,但是您將返回傳入的對象,而不是更高范圍的對象。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM