NodeJS выполнение команд оболочки в a для l oop при сохранении порядка выполнения - PullRequest
0 голосов
/ 01 марта 2020

Я экспериментирую с командами оболочки в узле, используя exec, но код не выполняется в ожидаемом порядке.

Это код.

const { exec } = require('child_process');

var newDataArray = []

for (var i = 0; i < 10; i++) {

    console.log(i)
    let printHelloCommand = 'echo hello' + i;

    exec(printHelloCommand, (err) => {
        if (err) {
            console.error(err)
        } else {
            newDataArray.push(i)
            console.log(newDataArray)
            console.log("------")
        }
    })
}
console.log("Printing array")
console.log(newDataArray)

Это вывод, который я получаю.

0
1
2
3
4
5
6
7
8
9
Printing array
[]
[ 10 ]
------
[ 10, 10 ]
------
[ 10, 10, 10 ]
------
[ 10, 10, 10, 10 ]
------
[ 10, 10, 10, 10, 10 ]
------
[ 10, 10, 10, 10, 10, 10 ]
------
[ 10, 10, 10, 10, 10, 10, 10 ]
------
[ 10, 10, 10, 10, 10, 10, 10, 10 ]
------
[ 10, 10, 10, 10, 10, 10, 10, 10, 10 ]
------
[ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10 ]

Выполнение кода повсюду. console.log(i) в строке 9 печатает полностью, когда он должен печатать только один раз al oop. Затем выполнение переходит к концу файла для печати на пустом массиве, и единственное значение, помещаемое в массив, - это 10, хотя оно должно толкать каждое значение i из 1-10 в массив.

Как мне решить эту проблему? Я попробовал обещания из библиотеки синей птицы, но, похоже, это не решило мою проблему.

Ответы [ 2 ]

0 голосов
/ 02 марта 2020

Ваш код не работает, потому что он не работает (var создает переменную, область действия которой находится за пределами l oop, к которой обращаются все обратные вызовы асинхронных операций):

for (var i = 0; i < 10; i++) {
    setTimeout(function() { console.log(i); }, 1000);
}

Объявляя переменную i как let область видимости становится блоком внутри l oop, и это создает отдельную переменную для каждой итерации l oop (каждый обратный вызов асинхронной операции имеет свою собственную переменную):

for (let i = 0; i < 10; i++) {
    setTimeout(function() { console.log(i); }, 1000);
}

Это исправит ваш код.

0 голосов
/ 01 марта 2020

Вы пытаетесь выполнить стиль обратного вызова внутри для l oop синхронно, что дает неожиданные результаты. Попробуйте версию обещания как это

const util = require("util");
const execAsync = util.promisify(require("child_process").exec);

(async() => {
  const newDataArray = [];

  for (var i = 0; i < 10; i++) {

    console.log(i);
    const printHelloCommand = `echo hello${ i}`;
    await execAsync(printHelloCommand);
    newDataArray.push(i);
    console.log(newDataArray);
    console.log("------");
  }
  console.log("Printing array");
  console.log(newDataArray);
})();


...