Node.jsとmysqlモジュールでサーバサイドのプログラムを作成しています。
###やりたいこと
for文の中にMySQLの問い合わせ処理をいくつか書き、
その結果を用いて配列を作成したい。
※SQL問い合わせのそれぞれの結果レコードは必ず1件になります。
mysqlクライアントを用いてクエリを事前に確認しています。
###分かったこと
・MySQLの問い合わせ処理は、mysqlモジュールを使って非同期処理で行われる。
・for文の中で非同期処理をしたい場合、Promiseを使用して、for文の外で結果を取る。
・Promise.allの.thenでプロミス全てが完了した時に処理を行える。
###問題点
- Promiseと即時処理/同期処理の実行順を保証できない
SQL文の結果を全て取得し終わってから配列を作成したいのに、
まだPromiseが完了していないのに最後のfor文が実行されてしまって、
SQLの結果が反映されない。
Promise.allと最後のfor文の間に、Promise.allが全て終わるまで待つようなブロッキングをする方法は無いのでしょうか。
- 2次元配列が直感と違う
javascriptでは2次元配列をサポートしていないらしく、
var array = [[1,2],[3,4],[5,6]];
をvar ar1 = array[0];var i = ar1[0];
の様にアクセスすればそれらしい事は出来るみたいですが、
下記ソースコードPromise.all([promisesA]).then(~~
内のresults.length
とsqlresults.length
の値が逆なのではないか?
直感では、results.length=31
と、SQLの結果sqlresults.length=1
ですが、
console.logで出力するとresults.length=1
、sqlresults.length=31
が返ってきます。
何故でしょうか。
宜しくお願い致します。
###ソースコード
少し長くなります。
lang
1//SQLでAValueを得るための処理 2var promisesA = []; 3var resultsA = []; 4function getA(arg){ 5 new Promise(function(resolve,reject){ 6 var query_sql = connection.query({ 7 sql : "~~~~", //略 8 timeout: 3000, 9 values : [~~~~] //略 10 },function(error,results,fields){ 11 if(error){ 12 reject(error,query_sql); 13 return; 14 } 15 resolve(results); 16 }); 17 }); 18} 19//SQLでBValueを得るための処理 20var promisesB = []; 21var resultsB = []; 22function getB(arg){ 23 new Promise(function(resolve,reject){ 24 var query_sql = connection.query({ 25 sql : "~~~~", //略 26 timeout: 3000, 27 values : [~~~~] //略 28 },function(error,results,fields){ 29 if(error){ 30 reject(error,query_sql); 31 return; 32 } 33 resolve(results); 34 }); 35 }); 36} 37//SQLでCValueを得るための処理 38var promisesC = []; 39var resultsC = []; 40function getC(arg){ 41 new Promise(function(resolve,reject){ 42 var query_sql = connection.query({ 43 sql : "~~~~", //略 44 timeout: 3000, 45 values : [~~~~] //略 46 },function(error,results,fields){ 47 if(error){ 48 reject(error,query_sql); 49 return; 50 } 51 resolve(results); 52 }); 53 }); 54} 55for(var i=0; i < 31; i++){ 56 promisesA.push(getA(~~~)); 57 promisesB.push(getB(~~~)); 58} 59Promise.all([promisesA]) 60 .then(function(results){ 61 for(var i=0; i < results.length; i++){ 62 var sqlresults = results[i]; 63 resultsA.push(sqlresults[0].AValue); 64 if(sqlresults[0].AValue > 0){ 65 promisesC.push(getC(~~~)); 66 } 67 } 68 }) 69 .catch(function(error,query){ 70 }); 71Promise.all([promisesB]) 72 .then(function(results){ 73 for(var i=0; i < results.length; i++){ 74 var sqlresults = results[i]; 75 resultsB.push(sqlresults[0].BValue); 76 } 77 }) 78 .catch(function(error,query){ 79 }); 80Promise.all([promisesC]) 81 .then(function(results){ 82 for(var i=0; i < results.length; i++){ 83 var sqlresults = results[i]; 84 resultsC.push(sqlresults[0].CValue); 85 } 86 }) 87 .catch(function(error,query){ 88 }); 89//SQL問い合わせの結果をもとに配列を作成 90for(var i=0; i < 31; i++){ 91 //配列作成 92}
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/08/09 14:24 編集
2016/08/09 16:36
2016/08/09 16:52