#はじめに
デバッグをしていると、なぜ、そのコードを実行しないのかと、不思議に思うことが、よくあります。
そこへは、来なくて、次のコードへ行っています。原因は、非同期だからかと頭の中では、わかっています。しかし、実際に遭遇してみると、そのことは、すっかり、忘れていて、他の理由を考えています。
なぜ、そこのブレークポイントで、停止しないのだろうかと、デバッグの設定が悪いのだろうかとか考えています。
そうではなく、そもそも、そこへ来ないコーディングをしているからということには、頭が回っていないのです。
プログラマーの頭は、もともと、シーケンシャル処理をベースに作られていますから、非同期は、特別扱いになっています。昔、コボルやフォートランでプログラムを作成していた頃は、シーケンシャルでした。その頃から、プログラム脳が養われてきたため、中々、そこから抜け出せないのかも知れません。
具体例
以下のコードで、ご説明します。
・まずい例
このコードの悪い点は、(A)も(B)も非同期で動作しますので、このコードでは、(C)がうまく表示できません。その結果、その下のコードのalert()文が実行していません。
//ブログ一覧ならば、pop表示
if(location.href.indexOf("https://search.ameba.jp/search/entry/")!==-1){
debugger;
console.log(location.pathname);
//このページで、likeQueryとacountをチェックする。
let lq;let acount;
// (A) ストレッジDBから、likeQueryの値を取得
likeQueryGet('likeQuery').then(data=>{
//
lq = data;
});
// (B) ストレッジDBから、acountの値を取得
acountGet('acount').then(data=>{
//
acount = data;
});
// (C) 取得した値を表示
console.log("lq = "+lq+" acount = "+acount);
//二つのパラメーターをチェック
//urlのパラメータがlqで、且つ、acountに一致しているか。
if( decodeURI(location.href).indexOf(lq+".html")!==-1){
//
if(location.href.indexOf(acount)!==-1){
//一致していれば、ここでpop表示する。
alert("「"+lq+"」で検索しました。");
}
}
}
・成功した例
このコードの場合は、lqの.then()の中で、acountGet()を出し、且つ、その.then()の中で、alert()を実行しています。これだと、非同期処理がうまく行っているので、alert()文が実行できます。
//ブログ一覧ならば、pop表示
if(location.href.indexOf("https://search.ameba.jp/search/entry/")!==-1){
debugger;
console.log(location.pathname);
//このページで、likeQueryとacountをチェックする。
let lq;let acount;
//
likeQueryGet('likeQuery').then(data=>{
//
lq = data;
//
acountGet('acount').then(data=>{
//
acount = data;
//
console.log("lq = "+lq+" acount = "+acount);
//
if( decodeURI(location.href).indexOf(lq+".html")!==-1){
//
if(location.href.indexOf(acount)!==-1){
//ここでpop表示する。
alert("「"+lq+"」で検索しました。");
}
}
});
});
}
・正常時の実行結果
アドレスバーのurlは以下のようになっています。
https://search.ameba.jp/search/entry/旅.html?aid=tecoyan
(注)このサンプルは、プラグインで、alert()文を表示しています。そのため、プラグインがインストールされていない場合は、alert()文は表示されません。近日中には公開予定ですので、まだ公開はされていません。
補足
もう一つのサンプルです。もともとは、このサンプルでご説明したかったのですが、上の不具合の優先度が高かったため、その説明を先にしました。
長いこと、不思議だったのですが、その原因を理解しました。
javascriptで、プログラミングしていますが、デバッガーでブレークポイントを設定しているにも関わらず、そこでブレークしないのです。console.log()やalert()を書いてもそこへ来ません。
途方にくれていたのですが、Agent iに聞いてみました。すると、書いてありました。その構文の後には制御が来ないと。それはそういう決まりなので、処理はできません。
その構文は、以下の構文です。
loacation.search(....................); .....には、urlのパラメーターが書かれます。
これは、引数を渡す記述です。この構文を実行すると、そのurlへリクエストを出して、新しいページがレスポンスとしてサーバーから返ってきます。つまり、リロードするものです。
そのため、先の制御が来ないのです。ページが初期化されてしまいます。そういう規約、規定、仕様なので仕方がありません。ここでは、もう少し、具体例として、以下にご説明いたします。
#実際の例
この構文(location.search(...))を使う場面は、以下のwebページになります。
あとがき
今回のようなケースは、すぐ忘れてしまいますので、再び、発生した場合は、また、悩むことになるのかと思ってしまいます。
しっかり、脳に焼き付けておきたいと思います。
補足)
もう一つ、サンプルです。
以下のケースは、2つの非同期の結果を待ってから、次の処理を行うコードです。
これでも、正常に動作しました。
//ブログ一覧ならば、pop表示
if(location.href.indexOf("https://search.ameba.jp/search/entry/")!==-1){
debugger;
console.log(location.pathname);
//このページで、likeQueryとacountをチェックする。
async function run() {
const [r1, r2] = await Promise.all([
likeQueryGet('likeQuery').then(data=>{window.lq = data;return data;}),
acountGet('acount').then(data=>{window.acount = data;return data;})
]);
// ここは全部完了後に実行される
console.log('全部完了', r1, r2);
if( decodeURI(location.href).indexOf(window.lq+".html")!==-1){
//
if(location.href.indexOf(window.acount)!==-1){
//ここでpop表示する。
alert("「"+window.lq+"」で検索しました。");
}
}
}
//
run().catch(console.error);
