Bluebird로 Node의 child_process.exec 및 child_process.execFile 함수를 약속하는 방법은 무엇입니까?
Node.js에서 Bluebird promise 라이브러리를 사용하고 있습니다. 훌륭합니다! 하지만 질문이 있습니다.
Node의 child_process.exec 및 child_process.execFile 의 문서를 살펴보면이 두 함수가 모두 ChildProcess 객체를 반환 하고 있음을 알 수 있습니다.
그렇다면 그러한 기능을 약속하는 권장 방법은 무엇입니까?
다음 작동합니다 (Promise 객체를 얻습니다).
var Promise = require('bluebird');
var execAsync = Promise.promisify(require('child_process').exec);
var execFileAsync = Promise.promisify(require('child_process').execFile);
그러나 원래 Node.js 함수의 원래 반환 값에 어떻게 액세스 할 수 있습니까? (이 경우 원래 반환 된 ChildProcess 객체에 액세스 할 수 있어야합니다.)
어떤 제안이라도 주시면 감사하겠습니다!
편집하다:
다음은 child_process.exec 함수의 반환 값을 사용하는 예제 코드입니다.
var exec = require('child_process').exec;
var child = exec('node ./commands/server.js');
child.stdout.on('data', function(data) {
console.log('stdout: ' + data);
});
child.stderr.on('data', function(data) {
console.log('stderr: ' + data);
});
child.on('close', function(code) {
console.log('closing code: ' + code);
});
그러나 약속 된 버전의 exec 함수 (execAsync from above)를 사용한다면 반환 값은 ChildProcess 객체가 아닌 promise가 될 것입니다. 이것이 제가 말하는 진짜 문제입니다.
호출에서 다음 두 가지를 반환하려는 것 같습니다.
- ChildProcess
- ChildProcess가 완료되면 해결되는 약속
그렇다면 "이러한 기능을 약속하는 권장 방법"은 무엇입니까? 하지 마십시오 .
당신은 대회 밖에 있습니다. Promise 반환 함수는 promise를 반환 할 것으로 예상됩니다. 두 개의 멤버 (ChildProcess 및 promise)가있는 개체를 반환 할 수 있지만 이는 사람들을 혼란스럽게 할 것입니다.
약속되지 않은 함수를 호출하고 반환 된 childProcess를 기반으로 약속을 만드는 것이 좋습니다. (아마도 그것을 도우미 함수로 감쌀 수 있습니다)
이런 식으로 코드를 읽는 다음 사람에게 매우 명확합니다.
다음과 같은 것 :
var Promise = require('bluebird');
var exec = require('child_process').execFile;
function promiseFromChildProcess(child) {
return new Promise(function (resolve, reject) {
child.addListener("error", reject);
child.addListener("exit", resolve);
});
}
var child = exec('ls');
promiseFromChildProcess(child).then(function (result) {
console.log('promise complete: ' + result);
}, function (err) {
console.log('promise rejected: ' + err);
});
child.stdout.on('data', function (data) {
console.log('stdout: ' + data);
});
child.stderr.on('data', function (data) {
console.log('stderr: ' + data);
});
child.on('close', function (code) {
console.log('closing code: ' + code);
});
다른 방법이 있습니다.
function execPromise(command) {
return new Promise(function(resolve, reject) {
exec(command, (error, stdout, stderr) => {
if (error) {
reject(error);
return;
}
resolve(stdout.trim());
});
});
}
execPromise(command).then(function(result) {
console.log(result);
}).catch(function(e) {
console.error(e.message);
});
또는 async / await 사용 :
try {
var result = await execPromise(command);
} catch (e) {
console.error(e.message);
}
Bluebird와 같은 추가 라이브러리 종속성보다 언어에 내장 된 표준 JS 약속을 사용하는 것이 좋습니다.
Node 10 이상을 사용 하는 경우 Node.js 문서util.promisify
는 Promise<{ stdout, stderr }>
객체 를 반환하는 사용 을 권장 합니다. 아래 예를 참조하십시오.
const util = require('util');
const exec = util.promisify(require('child_process').exec);
async function lsExample() {
const { stdout, stderr } = await exec('ls');
console.log('stdout:', stdout);
console.log('stderr:', stderr);
}
lsExample()
에서 오류를 먼저 처리합니다 stderr
.
모든 사용 사례를 다룰 수있는 방법은 없을 것입니다. 그러나 제한된 경우 다음과 같이 할 수 있습니다.
/**
* Promisified child_process.exec
*
* @param cmd
* @param opts See child_process.exec node docs
* @param {stream.Writable} opts.stdout If defined, child process stdout will be piped to it.
* @param {stream.Writable} opts.stderr If defined, child process stderr will be piped to it.
*
* @returns {Promise<{ stdout: string, stderr: stderr }>}
*/
function execp(cmd, opts) {
opts || (opts = {});
return new Promise((resolve, reject) => {
const child = exec(cmd, opts,
(err, stdout, stderr) => err ? reject(err) : resolve({
stdout: stdout,
stderr: stderr
}));
if (opts.stdout) {
child.stdout.pipe(opts.stdout);
}
if (opts.stderr) {
child.stderr.pipe(opts.stderr);
}
});
}
이것은 자식 프로세스에서 stdio를 캡처 할 수 있도록 인수 opts.stdout
및 opts.stderr
인수를 받습니다 .
For example:
execp('ls ./', {
stdout: new stream.Writable({
write: (chunk, enc, next) => {
console.log(chunk.toString(enc));
next();
}
}),
stderr: new stream.Writable({
write: (chunk, enc, next) => {
console.error(chunk.toString(enc));
next();
}
})
}).then(() => console.log('done!'));
Or simply:
execp('ls ./', {
stdout: process.stdout,
stderr: process.stderr
}).then(() => console.log('done!'));
Just want to mention that there's a nice tool that will solve your problem completely:
https://www.npmjs.com/package/core-worker
This package makes it a lot easier to handle processes.
import { process } from "CoreWorker";
import fs from "fs";
const result = await process("node Server.js", "Server is ready.").ready(1000);
const result = await process("cp path/to/file /newLocation/newFile").death();
or combine these functions:
import { process } from "core-worker";
const simpleChat = process("node chat.js", "Chat ready");
setTimeout(() => simpleChat.kill(), 360000); // wait an hour and close the chat
simpleChat.ready(500)
.then(console.log.bind(console, "You are now able to send messages."))
.then(::simpleChat.death)
.then(console.log.bind(console, "Chat closed"))
.catch(() => /* handle err */);
ReferenceURL : https://stackoverflow.com/questions/30763496/how-to-promisify-nodes-child-process-exec-and-child-process-execfile-functions
'program tip' 카테고리의 다른 글
복합 키 Entity Framework 만들기 (0) | 2020.12.31 |
---|---|
Docker 명령 줄의 Docker 레지스트리에서 특정 태그가있는 Docker 이미지를 찾으려면 어떻게해야합니까? (0) | 2020.12.31 |
* ngFor에서 동적 ID를 설정하는 방법은 무엇입니까? (0) | 2020.12.30 |
내 onItemSelectedListener가 ListView에서 호출되지 않는 이유는 무엇입니까? (0) | 2020.12.30 |
WebBrowser 전체 페이지 로딩 감지 (0) | 2020.12.30 |