質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

2回答

900閲覧

メソッドでの戻り値が適応されない

mote

総合スコア128

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2018/11/02 11:19

js

1let find = function(){ 2 let process = spawn("find",[DIR_COPY,"-name","*.pde"]); 3 process.stdout.on('data', (data)=>{ 4 console.log("data :" + data); 5 return data ; 6}); 7 8let open = function(path){ 9 let process = spawn("open",[path]); 10 process.on("exit",(code,signal)=>{ 11 console.log("file_open"); 12 }); 13} 14 15let postProcess = function() { 16let data = find() ; 17 open(data); 18}

上記のコードなのですが、findメソッドで得たdataという変数を
openメソッドの引数として扱いたいのですが、
dataの中身を見てみると、何も入っていません。

findメソッドの行なっている操作は、
「.pde」の名前がついたファイルのパスを所得しています。

openメソッドの行なっている操作は、
findで得たパスを開くといった操作なのですが、
どうもファイルが開かれません。

コンソールで戻り値で得たdataの
中身を見てみると何も入っていないようでした。

なぜ、戻り値が適応されないのでしょうか?
よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

takasima20

2018/11/02 13:08

find() が無いみたいなエラーは出てませんか?
mote

2018/11/02 13:58

回答ありがとうございます。エラーは出ていない状況です。
guest

回答2

0

ベストアンサー

spawnとともに用いるコールバック(onで登録する関数)の動作を勘違いしておられる気がします。

find関数は何もreturnしてませんので
let data = find()
としてもdataの中身はundefinedにしかなりません。

も少しfindでやっていることを補足すると

(1)子供プロセスでfindコマンドを実行する
(2)子供プロセスが何かをstdoutへ出力した際に呼び出されるコールバック関数を登録
(3)上記を行ったらサブプロセスからの出力や終了は待たずにすぐにreturn

となります。(2)で登録したコールバック関数から何かをreturnしてもそれはfind関数の戻り値とはなりません。

おそらく下記のようなことをしたかったのではないかと想像します。なお、spawnの用い方の変更以外に以下の点を変更しています。

  • find echoの連携にした

単に動作の確認のしやすさのためですが、
find . -name '*.pde' -exec echo {} \;
と同様のことを-execをnode側で行うような動作にしてみてます。

  • 関数定義

let name = function (...) {}ではなく単にfuntion name(...) {}とした

  • let

letにすべきところがないと感じたので全部constにしました。

t.js

js

1const { spawn } = require('child_process') 2 3function find(callback) { 4 const proc = spawn('find', ['.', '-name', '*.pde']) 5 const pid = proc.pid 6 console.log(`find: spawn pid=${pid}`) 7 proc.stdout.on('data', data => { 8 console.log(`data: ${data}`) 9 for (const s of ('' + data).split('\n').filter(s => s != '')) { 10 callback(s) 11 } 12 }) 13} 14 15function echo(path) { 16 const proc = spawn('echo', [path]) 17 const pid = proc.pid 18 console.log(`echo: spawn pid=${pid}`) 19 proc.stdout.on('data', data => { 20 console.log(`echo: ${data}`) 21 }) 22 proc.on('exit', (code, signal) => { 23 console.log(`echo: ${pid} done code=${code}, signal=${signal}`) 24 }) 25} 26 27function doProcessPipeline() { 28 find(echo) 29} 30 31doProcessPipeline()

結果例:

bash

1$ ls 2a.pde b.pde c.pde t.js 3$ node t 4find: spawn pid=4751 5data: ./b.pde 6./c.pde 7./a.pde 8 9echo: spawn pid=4752 10echo: spawn pid=4753 11echo: spawn pid=4754 12echo: 4752 done code=0, signal=null 13echo: 4753 done code=0, signal=null 14echo: 4754 done code=0, signal=null 15echo: ./b.pde 16 17echo: ./c.pde 18 19echo: ./a.pde 20 21$

投稿2018/11/02 14:25

KSwordOfHaste

総合スコア18394

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mote

2018/11/02 14:38

とても分かりやすいです!まさにfindではそのような事がしたかったです。 もう少し疑問点があるのですが、差し支えなければ答えていただきたいです。 今回、echoではなく、子供プロセスでのpdeファイルの実行をしたいのですが、 その場合はopenを使う必要は無いのでしょうか!?
KSwordOfHaste

2018/11/02 15:57

えーと、自分は拡張子pdeがどんなファイルなのか知りません。またopenコマンドって何かわかりません。ひょっとしてMacintoshユーザさんですか?調べてみるとMacintoshにはopenコマンドってのがあるらしいですが・・・
mote

2018/11/05 08:25

そうです! ありがとうございました。const s of ('' + data).split('\n').filter(s => s != '' " ここがあまり理解出来ていないので、教えていただきたいです...
KSwordOfHaste

2018/11/05 12:05

一つ一ついうと ('' + data) dataは文字列ではなくBuffer型なのでまずは('' + data)で文字列型に変換します。 ('' + data).split('\n') 一つの文字列を改行文字を区切りに複数の文字列へ分解しそれを要素とする配列に変換します。 ('' + data).split('\n').filter(s => s != '') 配列要素から「空文字列」を取り除いた新たな配列を生成します。 こういうのは実際に小さなコードを書いて動かしながら動作を把握するのがよいでしょう。 for (s of 'a//c'.split('/')) {  console.log(s) } for (s of 'a//c'.split('/').filter(s => s != '')) {  console.log(s) } という具合に書いて動かしてみればよいのです。
mote

2018/11/08 02:41

ありがとうございます。とても助かりました!
guest

0

2点問題があります。

  • datafind内のコールバックにローカルな変数なので、外部からは使えません。
  • .onで受けているように、processの動作は非同期実行なので、同期的な返り値として受けることはできません。

ただファイルを探すためだけなら、node-globに同期モードがありますので、そちらのほうが便利かもしれません。

投稿2018/11/02 13:32

maisumakun

総合スコア145183

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問