NodeJS-如何控制Promise的执行流程?

时间:2019-05-23 15:09:54

标签: node.js

我正在要求它尝试理解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);
})

如何在不影响性能的情况下控制执行流程?

1 个答案:

答案 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');