【初心者】Web SQL Databaseの同期処理化

- #### 背景

    
    業務アプリケーションを開発しています。その中でどうしてもWeb SQL Database処理を非同期処理に変更したい場面が出てきたためその内容を共有。Promiseオブジェクトの復習の意味も込めて共有します。

---
- #### 業務で遭遇した非同期にしたかった場面
    非同期処理にしたかった場面は、ある特殊な端末でWeb SQL Databaseを利用しなければならない（indexedDBやlocalStorageを利用できない端末）場面で発生しました。

---
#### 結論
`Promise`オブジェクトを利用。

- #### 検証事前準備
    検証用に掲示板サイトを用意。掲示板に投稿した際に、WebSqlDatabaseにinsertの処理を実行する。
    
    具体的には、登録時にフォームに入力した「氏名」、「内容」、「備考」と自動採番の「id」、並びに登録時刻を登録する。
    ![スクリーンショット 2023-04-08 13.26.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2781709/f781f121-4f30-e703-ba10-5fdc7b6f9c17.png)
    
    
    ソースは以下
    - `index.html`
        ```
        <body>
          <h2>掲示板</h2>
        
          <div id="formWrapper">
            <div>
              <div class="sideBySide verticalWidthOfTheForm">
                <p>氏名：</p>
                <input type="text" id="name" >
              </div>
        
              <div class="sideBySide verticalWidthOfTheForm">
                <p>内容：</p>
                <input type="text" id="content" >
              </div>
                
              <div class="sideBySide verticalWidthOfTheForm">
                <p>備考：</p>
                <input type="備考" id="remarks">
              </div>
        
              <input type="button" value="登録" onclick="insert()" class="verticalWidthOfTheForm" id="submit">
            </div>
          </div>
          
        </body>
        ```
    
    - `index.js`
    
        ```
        insertTransaction(request); //呼び出し元
        
       
        function insertTransaction(insertData) {
          db.transaction(function(tx) {
            tx.executeSql(
              "INSERT INTO posts (name, content, remarks, created) VALUES (?,?,?,?) ",
              insertData,
              null,
              null
            )
          });
        }
        ``` 

- #### 検証
    - まずは本当に非同期処理になっているのか確認。
        1. 上述で作成した`index.js`を以下のように変更してデバック情報を追記
            
            ```
            console.log("Before executing transaction"); // ← 追加
            insertTransaction(request);
            console.log("After executing transaction");  // ← 追加
            
            function insertTransaction(insertData) {
              db.transaction(function(tx) {
                tx.executeSql(
                  "INSERT INTO posts (name, content, remarks, created) VALUES (?,?,?,?) ",
                  insertData,
                  (tx, rs) => console.log("insert completed"), // ← 追加。insert成功時の処理
                  null
                )
              });
            }
            ```
        
        2. １の実行結果は以下のように非同期処理になっていました。
            ![スクリーンショット 2023-04-08 14.17.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2781709/ac9a08ac-6721-4205-4049-a37b29c96139.png)
    
    
    - そこで、Promiseオブジェクトを`db.transaction(function(tx) {`の前に入れて実行させてみる
        修正した`index.js`は以下
        ```
        console.log("Before executing transaction");
        await insertTransaction(request); //　呼び出し元のメソッドはasyncに変更。awaitも追記
        console.log("After executing transaction");
        
    
        function insertTransaction(insertData) {
          return new Promise(resolve => { // ← 追加
            db.transaction(function(tx) {
              tx.executeSql(
                "INSERT INTO posts (name, content, remarks, created) VALUES (?,?,?,?) ",
                insertData,
                (tx, rs) => {
                  console.log("insert completed");
                  resolve();　// ← 追加
                },
                null
              )
            });
          }) // ← 追加
        }
        ```
    
        これにより以下の実行結果になりました。
        ![スクリーンショット 2023-04-08 14.46.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2781709/062e5ccd-9d94-f5fb-5afc-74c7edb564d5.png)
    
    

- #### 所感
    今更、Web SQL Databaseで利用する業務は少ないとは思いますし、かなり初心者向けの内容（Promiseオブジェクトの内容）ですが参考になれば幸いです。


- #### 参考

    - Promiseオブジェクト
      https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise
    
    - リファレンス
      https://www.w3.org/TR/webdatabase/#asynchronous-database-api