nodejs 中执行 await promisify 处理后的 exec 函数与执行 execSync 函数的区别
promisify
Node.js 提供了一些工具来将回调风格的函数转换为返回 Promise 的函数。最常用的工具是 util.promisify
,它可以将传统的回调风格的函数转换为返回 Promise 的函数。
Node.js 中 执行 shell 的场景举例
exec
是一个异步函数。exec
函数是 Node.js 的 child_process
模块中的一个方法,用于执行一个 shell 命令。它会创建一个子进程来运行指定的命令,并在命令执行完成后调用回调函数。exec
是异步的,所以它不会阻塞事件循环。
const { exec } = require('child_process');
exec('ls -la', (error, stdout, stderr) => {
if (error) {
console.error(`exec error: ${error}`);
return;
}
console.log(`stdout: ${stdout}`);
console.error(`stderr: ${stderr}`);
});
既然是异步函数,可以用 promisify 将 exec 转换为 promise 函数,这样就可以用 async await 这种类似同步执行的写法了。
const { exec } = require('child_process');
const util = require('util');
const execPromise = util.promisify(exec);
async function runCommand() {
try {
const { stdout, stderr } = await execPromise('ls -la');
console.log('stdout:', stdout);
console.error('stderr:', stderr);
} catch (error) {
console.error('exec error:', error);
}
}
runCommand();
在 NodeJs 中需要同步地执行一个命令,可以使用 child_process
模块中的 execSync
方法,execSync
会阻塞事件循环,直到命令执行完成。
const { execSync } = require('child_process');
try {
const stdout = execSync('ls -la');
console.log(`stdout: ${stdout}`);
} catch (error) {
console.error(`execSync error: ${error}`);
}
那么问题来了,用 promisify
将 exec 转换为 promise 然后用 await 处理异步 和直接使用 execSync 有没有区别呢?表面上,使用 await 和 execSync 的效果一样,能够等脚本执行完毕后再执行后面的代码,然而,await
和 execSync
之间的关键区别在于它们的执行方式和对事件循环的影响。
差异点:
await
- 事件循环:
await
关键字用于等待一个 Promise 完成,但它不会阻塞整个事件循环。在等待期间,Node.js 仍然可以处理其他任务和事件。- 这意味着在等待命令执行的同时,Node.js 可以继续处理其他并发请求(例如,在服务器环境中处理其他 HTTP 请求)。
- 代码执行:
- 在
await
关键字所在的函数内部,代码执行会暂停,直到 Promise 完成。但这只是暂停当前函数的执行,不会影响整个事件循环。 - 其他异步任务(如 I/O 操作、定时器回调等)仍然可以继续执行。
execSync
- 事件循环:
execSync
是同步的,会完全阻塞事件循环,直到命令执行完成。- 在命令执行期间,Node.js 无法处理其他任务或事件。这意味着在高并发环境中使用
execSync
可能会导致性能问题,因为它会阻塞所有其他操作。
- 代码执行:
- 代码执行会暂停,直到
execSync
完成。这不仅影响当前函数,还会阻塞整个事件循环,导致 Node.js 无法处理其他并发任务。
callbackify
与 promisify 对应的,Nodejs 提供了callbackify 将 Promise 风格的函数转为 Error first 的 callback。
版权声明:
作者:东明兄
链接:https://blog.crazyming.com/note/3227/
来源:CrazyMing
文章版权归作者所有,未经允许请勿转载。
共有 0 条评论