Elsaの技術日記(徒然なるままに)

主に自分で作ったアプリとかの報告・日記を記載

MENU

簡単なWebアプリ作成 ~無駄な会議を撲滅しよう!! ~番外編~

無駄な会議を撲滅しよう!!シリーズですが、part4を上げてから6日経過しました。
なぜこんなに時間が空いてしまったか?というと、、、
はい!!物凄~~~く、手こずっておりまりました!!(泣)
そして、次回作挙げられるほどまだ完成には至っておりません(泣)。
f:id:Elsammit:20200602213323p:plain

part5では、会議時間や時間により発生した金額をグラフで表示したいと考えております。
当初は、「結果はsqlliteにあるしフロントエンド側にデータ持ってくるのも分かるし余裕でしょw」と思っておりました。
が、結構はまりました。。。

何にそんなにはまったのか。。。

今回、各日付・日時毎にパラメータを変化させながらDBから会議時間や金額を収集したく、
こちらのソースをサーバサイド(nodejs)側に作成し実行したのですが、
money配列はall 0であり、全く値が入っておりませんでした!!

app.post('/result_money',(req,res)=>{
    money = [];
    for(var i=0;i<7;i++){
        begin = req.body.beginTime[i];
        end = req.body.endTime[i];
        p = Get_MeetingList_Money(begin,end);
        p.then(function(db_money){
            money[i] = db_money;
        });
    }
    res.send(money);
});

function Get_MeetingList_Money(begin_time,end_time){
    var command ="select date(t) as date,time(t) as time,colum,SumSalary from MeetingList where date(t) > '" +  begin_time + "' and date(t) < '" +end_time +"';";
    return new Promise(resolve =>{
            db.get(command, function (err, rows) {
                resolve(test);
            });
    });
}

関数単体で動作させると問題なくデータが取得出来ており、begin_time、end_time変数は問題なく渡せておりました。
ではなぜ値が入らなかったのか。。。

それは!!
 javascript(& nodejs)がfor文を実行しただけで勝手に非同期処理になるため
です!!
知らなかった。。。
確かにDB操作時には非同期になってしまうため、Promiseと.thenを用いて同期処理にすることは知ってましたが、まさかループ処理ですら非同期処理にしてしまうなんて。。。
恐るべし、javascript !!
f:id:Elsammit:20200602213815p:plain

そして、ここからどのように解決すればよいか?調査や動作確認を繰り返しました。
 ・aync、awaitを使ってループ処理を同期処理に出来ないか?
 ・Promise、.thenを使って同期処理に出来ないか?
 ・Promise.allを使用すれば同期処理になるのでは?
 ・etc...
繰り返しましたがどれもこれもうまくいかず。。。
ループ処理単体やDB操作単体ではうまくいくのだが、上記のソースのようなループ処理+DB操作のように組み合わせるとどうしても非同期処理になり、正しい値が得られない(泣)。

そして遂に、、、諦めました!!w
サーバサイドでループ処理+DB操作を行うのではなく、
・サーバサイド:DB操作
・フロントサイド:ループ処理
の構成しました。
【フロントサイド】

async function do_Init(days){
    var select = document.getElementById("Init");
    var option_def = document.createElement("option");
    option_def.text = "";
    option_def.value = "null";
    select.appendChild(option_def);
    
    for(var i=0;i<50;i++){
      await Time_ajax(i,select);
    }
}

【サーバサイド】

app.post('/result_money_sub',(req,res)=>{
    money = [];
    begin_time = req.body.Time[0];
    end_time = req.body.Time[1];

    p = Get_MeetingList_Money(begin_time,end_time);
    p.then(function(money_array){
        res.send(money_array); 
    });
});

function Get_MeetingList_Money(begin_time,end_time){
    var list_buf = [];
    var command ="select date(t) as date,time(t) as time,colum,SumSalary from MeetingList where date(t) > '" +  begin_time + "' and date(t) < '" +end_time +"';";
    return new Promise(resolve =>{
            db.all(command, function (err, rows) {
                rows.forEach(function(row){
                    list_buf .push(row);
                });
                resolve(list_buf );
            });
    });
}

これで問題なく動作させることが出来ました!!
ふぅ~よかった!!

一応、グラフ表示までは出来ているのですが、一部バグが残っているので。
ソースコードをきれいにして、part5として後日報告させて頂きます!!