Пытаясь дождаться заполнения списка, прежде чем итерировать его, NodeJS - PullRequest
0 голосов
/ 04 апреля 2019

У меня есть код, который берет загруженный файл, выполняет его и получает вывод.Затем он сравнивает эти выходные данные с ожидаемыми, чтобы проверить, правильно ли выполнялся сценарий.

Сейчас я пытаюсь улучшить эту функциональность, чтобы загруженный файл запускался несколько раз, каждый раз сравниваясь с другим ожидаемым выводом или «контрольным примером».Затем я хочу вставить «правильный» или «неправильный» в массив результатов, чтобы я мог пройти через этот массив в конце и проверить, есть ли какие-либо «неправильные» (не прошел ли файл какой-либо тестовый пример).

  • Я пробовал только обратные вызовы внутри каждой функции.
  • Я попытался использовать 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 () , но все еще без изменений.

Возможно, я не правильно использую асинхронные / обратные вызовы, любая помощь очень ценится.

1 Ответ

0 голосов
/ 05 апреля 2019

Ваша функция executeFileAsync в настоящее время вызывает executeFile с обратным вызовом, который ожидает два аргумента, но затем executeFile вызывает этот execFileCb всегда только с одним аргументом, который интерпретируется как ошибка. Также не следует использовать throw в асинхронном обратном вызове.

Вместо этого объедините их в одну функцию:

function executeFile(filename) {
  return new Promise(function(resolve,reject){
    //pathToUpload is a str path to where the upload is stored

    const child = execFile('python', [pathToUpload], (err,stdout,stderr) => {
      if (err) reject(err);
      else resolve(stdout); //Callback with output of file
    });
  });
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...