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

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

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

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

Node.js

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

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

Q&A

解決済

1回答

2724閲覧

mysqlに接続する処理を書いているがawait/asyncが機能しない。

coldr

総合スコア7

MySQL

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

Node.js

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

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

0グッド

0クリップ

投稿2021/05/14 12:42

typescript+node.jsを用いてMysqlに接続する処理を書いています。接続が失敗した時には間隔を置いて最大5回までリトライするようにしたいと考えているのですが、リトライ処理が完了する前に結果が返ってきてしまいます。接続処理が成功した時にはtrueを、失敗したときにはfalseを返す仕組みにするにはどうすればよいでしょうか。お知恵を拝借したく思います。よろしくお願いいたします。

接続処理側のコード

typescipt

1const mysql = require('mysql'); 2let connection; 3let cnt = 0; 4 5 6export const cm_dbconnect = async() => { 7 8 var dbInfo = { 9 host : '127.0.0.1', 10 user : '****', 11 password : '**********' 12 } 13 14 let db = mysql.createConnection(dbInfo); 15 16 const attemptConnection = async() => { 17 console.log('Attempting to connect to db') 18 19 20 21 db.connect(async function (err) { 22 if (err) { 23 24 cnt += 1; 25 console.log('Error connecting to database, try again in 1 sec...') 26 db.destroy() 27 if (cnt<5) { 28 console.log(cnt); 29 30 function settimeoutpromise() { 31 return new Promise((resolve, reject) => { 32 setTimeout(() => { 33 cm_dbconnect(); 34 resolve("end") 35 }, 1000); 36 })} 37 await settimeoutpromise(); 38 39 } 40 } 41 }) 42 43 44 } 45 await attemptConnection() 46 47 48 49 module.exports = db; 50 if(cnt<5) { 51 return {result: true, errCode: "", errDetail: ""}; 52 } else { 53 return {result: false, errCode: "", errDetail: ""}; 54 } 55 56}

コントローラー側のコード

typescript

1export const Controller = async () => { 2 3 4 let connect = await cm_dbconnect(); 5 6 let db = require(''); 7 let sql = 'select *** from ***;'; 8 db.query(sql, function (error, results, fields) { 9 console.log(results); 10 11 }) 12 13 console.log("aaaa"); 14 console.log(connect); 15 16 17 } 18let test = Controller();

結果

Attempting to connect to db aaaa { result: true, errCode: '', errDetail: '' } Error connecting to database, try again in 1 sec... 1 undefined Attempting to connect to db Error connecting to database, try again in 1 sec... 2 Attempting to connect to db Error connecting to database, try again in 1 sec... 3 Attempting to connect to db Error connecting to database, try again in 1 sec... 4 Attempting to connect to db Error connecting to database, try again in 1 sec...

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

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

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

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

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

guest

回答1

0

ベストアンサー

残念ながら、mysqlライブラリはasync-awaitに対応していません(コールバックにasync関数を渡しても、返り値のPromiseを活かす場がないので無意味です)。

async-awaitに持ち込みたければ、自分でnew Promiseしてコールバックでresolverejectを行う必要があります。

(なお、それを行ったmysql-awaitというパッケージも存在するようです)

投稿2021/05/14 12:47

maisumakun

総合スコア145208

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

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

coldr

2021/05/14 13:41

ご回答ありがとうございます。私としてはリトライ接続のあとに結果が返って来るのであれば、コールバック、await/asyncどちらを用いても構わないのですが、どのような構成になるかもう少し具体的にご教授いただくことは可能でしょうか。
maisumakun

2021/05/14 13:47

ループで何度も繰り返すような場合は、async-awaitを使うほうが圧倒的に楽です。
coldr

2021/05/14 14:11

ご回答ありがとうございます。今回の構成でasync/awaitを用いるとなると、今までコールバックを用いてエラーハンドリングしていた箇所を何か別の指標を用いてDBに接続できたか否か判別しなければならないと思うのですが、何を用いればよいか分かりかねています。何かテスト用のSELECT文を打って疎通確認してもよいのですが、もう少しエレガントな手法があればご教授いただきたいです。
maisumakun

2021/05/14 14:13

awaitで受けたPromiseがrejectとなった場合、awaitが例外を投げますので、例外処理として対応が可能です。
coldr

2021/05/14 15:10

ご回答ありがとうございます。例えば msql.createConnection({ host: '127.0.0.1', user: '***', password: '****', }).then(()=>{console.log("aaa")}) .catch(()=>{console.log("bbb")}) とすることでハンドリングすることは可能だと思いますが、msql.createConnectionから返却されたpromiseを変数に格納し、rejectかresolveかを判別するということは可能なのでしょうか。初歩的な質問で恐縮ですが、ご教授よろしくお願いいたします。
maisumakun

2021/05/14 21:29 編集

> msql.createConnectionから返却されたpromiseを変数に格納し、rejectかresolveかを判別するということは可能なのでしょうか。 すでに書いたように、Promiseをawaitで受ければ、rejectの場合例外となるのでtry-catchで処理できます(awaitなしでPromiseのまま受け取った場合、同期的に状態は変化しませんので、そもそも何もできません)。
maisumakun

2021/05/14 21:37

> 接続処理が成功した時にはtrueを、失敗したときにはfalseを返す仕組みにするにはどうすればよいでしょうか。 同期的に結果を返すことは不可能です。その関数自体がPromiseを返すような形を取る(async-awaitで書いてもそうなる)しかありません。
coldr

2021/05/17 15:46

ご助言頂いた通り実装したところ、意図していたように動作しました。誠にありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問