我正在要求它尝试理解nodeJS。我试图使用以下代码来一次执行CMD操作,但是由于事件循环(我认为),它以随机变化的方式执行。这是我的代码:
const exec = require('child_process').exec;
//os_func's execCommand is incharge of executing cli strings using a promise
function os_func() {
this.execCommand = function (cmd) {
return new Promise((resolve, reject)=> {
exec(cmd, (error, stdout, stderr) => {
if (error) {
reject(error);
return;
}
resolve(stdout)
});
})
}
}
//start
var os = new os_func();
os.execCommand('pwd').then(res=> {
console.log("os1 >>>", res); //sometimes first, sometimes second
}).catch(err=> {
console.log("os >>>", err);
})
os.execCommand('pwd').then(res=> {
console.log("os2 >>>", res); //sometimes first, sometimes second!
}).catch(err=> {
console.log("os >>>", err);
})
如何在不影响性能的情况下控制执行流程?
答案 0 :(得分:2)
首先,使基于(err, ...args)
的回调异步的JS方法是使用为此目的而构建的util.promisify
。示例:
const {exec} = require('child_process');
const {promisify} = require('util');
const exec_async = promisify(exec);
exec_async('pwd').then(({stdout, stderr}) => console.log(stdout))
// you can use exec_async instead of os.execCommand
然后,您必须了解承诺是异步的。为简单起见,在调用和兑现承诺之间可能会发生事情。异步性是JS的基本组成部分之一-我不会详细介绍它,但是如果您在理解此概念时遇到困难,建议从MDN's guide on asynchronous programming in JS开始。
基本上在您的代码中,这可能发生:
time
|
| os.execCommand('echo hello from 1')
| .then(res=> console.log('os1 >>> ', res))
| os.execCommand('echo hello from 2')
| .then(res=> console.log('os2 >>> ', res))
V
Output:
os1 >>> hello from 1
os2 >>> hello from 2
但这也是
time
|
| os.execCommand('echo hello from 1')
| os.execCommand('echo hello from 2')
| .then(res=> console.log('os2 >>> ', res))
| .then(res=> console.log('os1 >>> ', res))
V
Output:
os2 >>> hello from 2
os1 >>> hello from 1
还有其他一些怪异的组合。如果要确保一个命令先于另一个命令执行,则应使用then
链接诺言:
exec_async('echo hello from 1')
.then(console.log)
.then(
exec_async('echo hello from 2')
.then(console.log)
)
嵌套的then
可能会影响可读性,因此您可能会选择async/await
syntax:
const hello1 = await exec_async('echo hello1');
const hello2 = await exec_async('echo hello2');