はじめに
このような経験は誰にでもあると思います。
console.log()ならば、問題なくデバッグが進んでいたと思います。
なぜ、alert()文だとダメなのかについての失敗例を示したいと思います。
何をデバッグしていた時か
アメバのブログを作成しているときに、編集画面のサイドバーにyoutubeボタンがあります。このyoutubeボタンでクエリー入力して検索ボタンを押したときに発生しました。
実際の症状を具体的にご説明いたします。
このyoutube検索でやりたかったことは、アメバにyoutube動画を埋め込むことと同時に検索結果のリストをサーバーへ保存することです。このDB保存処理をプラグインで処理しようとしました。つまり、アメバ編集処理とプラグインの処理の2つの処理を実行したかったことです。
このデバッグで、深く考えもせずにalert("検索ボタンがおされました。")文を以下のソースにあるように挿入していたことです。
サンプルコード
//アメバ編集画面のサイドバーの検索ボタンをクリック
$("#js-searchButton-youtube").on('click', () => {
setTimeout(() => {
//検索ボタンが押されて3秒後にDBへ保存
let query_key;
let aaa = document.getElementsByClassName("js-video-item");
if (aaa.length !== 0) {
//ここで、リストデータを生成して保存
//val.innerHTML この中の<imgタグのsrcを取得
//val.innereText タイトル
let src;
let title;
let data = [];
let aa = {};
let thumb;
$.each(aaa, (i, val) => {
//<imgタグを抽出
src = val.innerHTML.match(/<img[\s\S].*\/div><div/)[0].replace(/<\/div><div/, "");
title = src.split("alt=")[1].replace(/>/, "");
title = title.replace(/"/g, "");
thumb = src.replace(/alt=.*>/, ">");
//srcからサムネイルとタイトルを分けて
aa = {"サムネイル": thumb, "タイトル": title};
data.push(aa);
});
//data(配列データ)を保存します。サーバへ
//このリストをサーバーへ保存
//<imgタグのhtmlデータ
query_key = $("#js-searchBox-youtube")[0].value;
var params = {
query_key: query_key,
data: data
};
var resp = $.ajax({
url: 'https://xxx.xxx.net/slim/save_ameba_youtube_list.php',
type: 'POST',
dataType: 'html',
data: params,
cache: true,
async: false
}).responseText;
//
alert("リストデータを" + resp);
alert("リストがロードされました。 レングス = " + $(".js-video-item").length);
}
else {
//レングス0
}
}, 3000);
alert("検索ボタンがおされました。");
});
コードの処理内容
先頭にある、
$("#js-searchButton-youtube").on('click', () => {
このコードはプラグインのコードで、検索ボタンのclickイベントをひろうリスナー処理の入り口です。アメバのclick処理ではありません。アメバのclick処理はアメバ編集処理の本体側で行っています。そちらでは、youtubeAPIを使用してクエリーをもとに検索を実行しています。実行後はサイドバーに検索結果のリストを表示します。
ここのコードはプラグインのコードで同じ検索ボタンのclickイベント処理を定義しています。ここで行いたいことは、アメバの検索結果のリストをもとにそのデータをDB保存することです。そのためには、検索結果のリストが表示されていることが前提条件になります。その条件を満たすため、3秒のタイマーをセットしました。3秒経てば、検索結果リストも表示されているはずです。実際はもっと短い時間で表示されていると思います。タイマー値を短くしてテストすれば確認できると思いますが、確実性のため、少し長めに設定しました。
そこで、今回の本題に入ります。うかつにもsetTimeout()の後に、alert("検索ボタンがおされました。");のalert()文をいれていました。ここへalert()文を置いたのが失敗の原因でした。
考えみれば、当然です。setTimeout()でタイマー処理を登録後に直ちにalert()文で処理を停止しています。このため、OKボタンを押さない限りアメバの編集処理側ではいつまで経ってもクエリーの検索が進行しません。ここで、OKボタンをクリックすると先に3秒過ぎているため、タイムアウト処理が実行します。しかし、まだ、検索結果リストが表示されていませんので、エラーになります。この原因がわかりませんでした。
落ち着いて調べてみたら、このalert()文が悪さをしていたことがわかりました。さっそく、コメントアウトして実行してみたら、正常に動作しました。
理由は、プラグイン側で3秒待っている間に、アメバ編集側でクエリーの検索が終了してリストを表示しています。3秒後のタイムアウト処理では、すでに検索結果リストが表示されているため、それらのリストデータをDBへ保存できました。
alert()文には気をつけたい
これが、console.log()であれば、問題なくDB保存できていたはずです。console.log()はalert()文のような停止して人によるボタン操作を待つ必要がないため、3秒以内にはアメバ編集側の検索処理は終了しているはずです。
あとがき
このような迂闊なミスはプログラミングしているときにはよく起こります。よく考えてみれば当然のミスをその時は気づかずに永遠と時間を無駄にしています。
コードのテスト結果を早く知りたいという焦りがミスの原因を作っています。
プログラマーはいつもこのことを反省しながらコードを作っています。残念ながらその繰り返しです。再反省します。