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

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

新規登録して質問してみよう
ただいま回答率
85.48%
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Node.js

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

JavaScript

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

Q&A

解決済

4回答

2619閲覧

node.jsのasyncモジュールで、waterfallの外に変数を出したい

退会済みユーザー

退会済みユーザー

総合スコア0

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Node.js

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

JavaScript

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

0グッド

0クリップ

投稿2018/04/18 08:32

node.js:v9.5.0
MySQL:5.7.21
MacOS:10.12

node.jsのasyncモジュールを使うことが条件となります。

MySQLの結果を加工して他の関数でいじりたいのですが、asyncモジュールのwaterfallを使って出した結果はwaterfallの外に出すことができません。

例えば下のコードの結果は、

javascript

1'use strict'; 2 3const async = require('async'); 4const mysql = require('mysql'); 5 6let arr = []; 7 8async.waterfall([ 9 (next) => { // MySQL接続 10 const conn = mysql.createConnection({ 11 host: 'localhost', 12 user: 'root', 13 password: '', 14 database: 'table' 15 }); 16 17 conn.connect((err) => { 18 if (err) throw err; 19 return next(null, conn); 20 }); 21 }, 22 (conn, next) => { 23 const sql = 'SELECT * FROM foo'; 24 conn.query(sql, (err, data) => { 25 conn.end(); 26 if (err) throw err; 27 28 // SQLの結果をpushで配列にする 29 async.eachSeries(data, (hoge, callback) => { 30 arr.push(hoge.id); 31 return callback(); 32 }); 33 return next(null, arr); 34 }); 35 } 36], (err, arr) => { 37 if (err) throw err; 38 console.log('asyncの中:', arr); // [ 80, 81, 86, 87, 88, 89, 91, 17, 31, 32, 33 ] 39}); 40 41console.log('asyncの外:', arr) // []

text

1asyncの外: [] 2asyncの中: [ 80, 81, 86, 87, 88, 89, 91, 17, 31, 32, 33 ]

のようなイメージとなります(当たり前ですが)。
結果arrをwaterfallの外に出す方法はないでしょうか。

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

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

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

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

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

y_waiwai

2018/04/18 10:28

出すことが出来ないとはどーゆーふーにできないのか説明してください
退会済みユーザー

退会済みユーザー

2018/04/18 10:32

恐縮です。async.waterfallの外でlet arr宣言しているので、いったんarrに結果が入ったら、そのままasync.waterfallの外でもarrに値が入ったままになって欲しいのですが、async.waterfallの外に出てしまうとarrの中の値が空になってしまう、ということなのですが、これでわかりますでしょうか。
guest

回答4

0

タイムマシンでも使わない限り無理です。

というのも、async.waterfallの中身はあとから実行されるものなので、console.log('asyncの外:', arr)のほうが先に実行されるからです

「待たせたい」のに「async.waterfallの外に書きたい」というのは、希望自体が矛盾しています。

投稿2018/04/18 10:36

maisumakun

総合スコア145183

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

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

0

ベストアンサー

たんに非同期関数が実行される前にarrを読んでいるということはないでしょうか
関数が終了するのを待って読んでみればどうでしょう

投稿2018/04/18 10:35

y_waiwai

総合スコア87749

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

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

退会済みユーザー

退会済みユーザー

2018/04/19 08:34

「やっぱりまたコレか・・・」と思いコードを見直してみました。ありがとうございました。
guest

0

回答を下さった皆様、ありがとうございました。
正解でなくてもヒントにはなりました。

実際のコードは非常に複雑で長いのでここでは紹介出来かねますが、うまくいかなかった原因はコールバック関数の抜けとか、位置が違うという理由でした。

なので上記のコードがfunctionの中に入っていた場合、きちんとarrの中に値は入ってきます。
以下、正しいコードの例となります。

javascript

1'use strict'; 2 3const async = require('async'); 4 5let hoge = [0, 1, 2, 3, 4]; 6let foo = []; 7 8let main = () => { 9 async.waterfall([ 10 (next) => { 11 async.eachSeries(hoge, (h, callback) => { 12 sub(h, (t) => { 13 foo.push(t); 14 return callback(); // このcallbackの位置が違っていた 15 }); 16 }, (err) => { // ここから 17 return next(null); 18 }); // ここまでが抜けていた 19 } 20 ], (err) => { 21 if (err) throw err; 22 console.log(foo); 23 }); 24} 25 26let sub = (i, callback) => { 27 let e = i + 1; 28 return callback(e); 29} 30 31main();

省略しちゃいましたが、実際にはasync.eachSeriesの中にMySQLの結果を入れています。
正しく書けば、ここでいうfooはきちんと表示されます。

コールバックの書き忘れや書く位置が違うミスが多いです。
エラーを出してくれるツールでもあればいいのですが。。。

投稿2018/04/19 08:36

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

0

async.seriesを使って

  1. waterfallの処理
  2. waterfallで得た値を使って実行したい

処理でどうでしょうか?(少し強引ですが

投稿2018/04/18 11:40

shoya.shiraki

総合スコア430

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問