У меня есть код, который берет загруженный файл, выполняет его и получает вывод.Затем он сравнивает эти выходные данные с ожидаемыми, чтобы проверить, правильно ли выполнялся сценарий.
Сейчас я пытаюсь улучшить эту функциональность, чтобы загруженный файл запускался несколько раз, каждый раз сравниваясь с другим ожидаемым выводом или «контрольным примером».Затем я хочу вставить «правильный» или «неправильный» в массив результатов, чтобы я мог пройти через этот массив в конце и проверить, есть ли какие-либо «неправильные» (не прошел ли файл какой-либо тестовый пример).
- Я пробовал только обратные вызовы внутри каждой функции.
- Я попытался использовать await и async на getArray, как показано ниже
- Использование обоих обратных вызовов и асинхронного вместе.
Это код родительской функции, который вызывает созданный массив и хочет выполнить итерацию по нему после того, как он был создан.
var resultsArr = await getResults(file.name, files.length, markerDir);
//file.name is the name from the uploaded file object
//files.length is the number of subdirectories (number of testcases to run against)
//markerDir is the str path to where these testcases are stored
if (resultsArr){
for(var i=0;i<resultsArr.length;i++) {
if (resultsArr[i] == "incorrect"){
checkForMarkerCb('incorrect'); //Calls back to frontend to
break; //display result on web app
}
else if (i+1 == resultsArr.length) {
checkForMarkerCb('correct');
}
}
}
Следующее находится внутриФункция getResults, которая вызывается выше
for(var i=1; i<=fileLength; i++) {
var sampleOut = markerDir + '/test' + i + '/stdout.txt';
//Grab expected stdout.txt
var markerOut = fs.readFileSync(sampleOut, 'utf-8', function(err){
if (err){
throw err;
};
});
//Run the file and grab the output
executeFile(filename, function(fileOut){
//Compare output with sample stdout
if (markerOut == fileOut){
resultsArr.push('correct');
}
else {
resultsArr.push('incorrect');
}
});
}
//If results array has a response for each testcase
if (resultsArr.length == fileLength) {
return resultsArr;
}
Реализация executeFile () в соответствии с запросом:
function executeFile(filename, execFileCb){
//pathToUpload is a str path to where the upload is stored
const child = execFile('python', [pathToUpload], (err,stdout,stderr) => {
if (err) {
throw err;
}
execFileCb(stdout); //Callback with output of file
});
}
function executeFileAsync(filename) {
return new Promise(function(resolve,reject){
executeFile(filename, function(err, data){
if (err !== null) reject(err);
else resolve(data);
});
});
}
, которая была вызвана внутри getResults () с использованием
var fileOut = await executeFileAsync(filename)
- Исходная функция, которая вызывает getResults () .
- getResults () : которая получает путь к каждому каталогу и вызывает толкает результаты сравнениявыводит в массив результатов.
- executeFile () : использует 'child_process' для запуска файла и выполняет обратный вызов с выводом.
Я ожидаю, что код будет ожидать возврата getResults с resultsArr, чтобы цикл for мог выполнять итерацию и проверять наличие «неправильных».Вместо этого getResults возвращает до заполнения resultsArr.
Используя некоторое ведение журнала, я вижу, что код для проверки markerOut == fileOut выполняется в конце после того, как цикл getResults () for уже выполнензавершено.Я попытался настроить вызов executeFile () , чтобы он также был асинхронным / ожидающим, подобно тому, как вызывается getResults () , но все еще без изменений.
Возможно, я не правильно использую асинхронные / обратные вызовы, любая помощь очень ценится.