Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/35.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript NodeJS-在数组中的每个元素之间按顺序循环并超时_Javascript_Node.js_Arrays_Loops_Timeout - Fatal编程技术网

Javascript NodeJS-在数组中的每个元素之间按顺序循环并超时

Javascript NodeJS-在数组中的每个元素之间按顺序循环并超时,javascript,node.js,arrays,loops,timeout,Javascript,Node.js,Arrays,Loops,Timeout,我有一个数组中需要按顺序运行的命令列表: const commands = [ `git clone https://github.com/EliLillyCo/${repo}.git`, `cd ${repo}`, `git checkout -b ${branch}`, 'cp ../codeql-analysis.yml .github/workflows/', 'git add .github/workflows/codeql-analysis.yml', `git

我有一个数组中需要按顺序运行的命令列表:

const commands = [
  `git clone https://github.com/EliLillyCo/${repo}.git`,
  `cd ${repo}`, `git checkout -b ${branch}`,
  'cp ../codeql-analysis.yml .github/workflows/',
  'git add .github/workflows/codeql-analysis.yml',
  `git push --set-upstream origin ${branch}`,
  'cd ../',
  `rm -r  ${repo}`,
];
由于命令依赖于正在运行的前一个命令,因此需要按顺序运行这些命令

此外,在运行下一个命令之前,每个命令需要等待3秒钟,因为有时命令需要时间,尤其是command1和command5

我使用标准的
for
循环,然后使用调用函数来运行命令的
setTimeout()
,例如:


const a = require('debug')('worker:sucess');
const b = require('debug')('worker:error');

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

function execCommand(command) {
  exec(command, (error, stdout, stderr) => {
    if (error) {
      b(`exec error: ${error}`);
      return;
    }
    a(`stdout: ${stdout}`);
    b(`stderr: ${stderr}`);
  });
}

const commands = [
   `git clone https://github.com/EliLillyCo/${repo}.git`,
   `cd ${repo}`, `git checkout -b ${branch}`,
   'cp ../codeql-analysis.yml .github/workflows/',
   'git add .github/workflows/codeql-analysis.yml',
   `git push --set-upstream origin ${branch}`,
   'cd ../',
   `rm -r  ${repo}`,
 ];

for (let i = 0; i < commands.length; i++) {
  setTimeout(execCommand(commands[i]), 3000);
}

解决在使用超时时按顺序循环数组的问题的最佳方法是什么?

我会让
execCommand
返回一个承诺,以便您知道何时完成;你不能依赖超时(如果任务需要三秒钟以上怎么办?),因为大多数命令的完成速度都比这快得多,超时会不必要地拖延时间

下面是返回承诺的
execCommand

function execCommand(command) {
    return new Promise((resolve, reject) => {
        exec(command, (error, stdout, stderr) => {
            if (error) {
                b(`exec error: ${error}`);
                reject(error);
                return;
            }
            a(`stdout: ${stdout}`);
            b(`stderr: ${stderr}`);
            resolve();
        });
    });
}
然后,如果您有顶级
wait
可用(modern Node.js和ESM模块):

如果没有,请将其包装在
async
iLife中:

(async () => {
    for (const commmand of commands) {
        await execCommand(command);
    }
})().catch(error => {
    // ...report/handle error...
});


或者,如果您想将执行与处理
stdout
/
stderr
分开,您可以直接使用on
exec
,但将它们结合在一起对您所做的改动最小,这就是我一直坚持的观点。

当前,您不能保证在调用下一个命令时上一个命令会完成。3000毫秒后自动调用下一个,但上一个可能需要比预期更长的时间,并且尚未结束

您应该添加一个机制来等待每个命令,然后启动下一个命令。下面介绍如何使用
async/await

const util = require('util');
const exec = util.promisify(require('child_process').exec);

const commands = [ ... ];

const execCommand = async (command) => {
    try {
        await exec(command)
    } catch (error) {
        b(`exec error: ${error}`);
        return;
    }
    a(`stdout: ${stdout}`);
    b(`stderr: ${stderr}`);
}

(async () => {
    for (let command of commands) {
        await execCommand(command);
    }
})();

正确的语法是
setTimeout(execCommand,3000)
setTimeout(()=>{execCommand(commands[i])},3000)
wait execCommand(commands)的意思是:
等待执行命令(command)它仍然没有等待上一个命令完成。在最后一个命令完成之前,这些命令似乎仍在运行?@user3180997-是的,
execCommand(commands)
应该是
execCommand(command)
,对此表示抱歉。根据,在进程退出之前,
exec
不会调用其回调。因此,如果你认为承诺在那之前就已经达成,它暗示了三件事之一:1。您没有完全正确地实现上述内容(抱歉:-),或者2。命令已完成,您看到的有不同的解释,或者。。。。。。3.您正在调用的进程只是启动另一件不会阻止您正在创建的进程终止的事情,并在后台继续其工作。但是上面的
execCommand
肯定会等待进程开始退出,至少根据Node.js文档是这样。不用担心,只是想再次检查一下。当我把
cd../
作为第一个命令,把
pwd
作为第二个命令时,
pwd
打印出我当前所在的目录,而不是
cd../
应该放我进去的目录。因此,我认为它要么没有运行
cd../
要么
pwd
首先出现。感谢您的响应。它仍然没有等待上一个命令完成。在最后一个命令完成之前,命令似乎仍然在运行?嗯,我不明白为什么,因为一切都返回一个承诺,并且
按顺序等待
,我知道,我已经添加了一张
cd../
pwd
,并且pwd在cd出现之前打印出来:/
(async () => {
    for (const commmand of commands) {
        await execCommand(command);
    }
})().catch(error => {
    // ...report/handle error...
});
const util = require('util');
const exec = util.promisify(require('child_process').exec);

const commands = [ ... ];

const execCommand = async (command) => {
    try {
        await exec(command)
    } catch (error) {
        b(`exec error: ${error}`);
        return;
    }
    a(`stdout: ${stdout}`);
    b(`stderr: ${stderr}`);
}

(async () => {
    for (let command of commands) {
        await execCommand(command);
    }
})();