こんにちは。
田中です。
Webからダウンロードをする、という処理は何かとWebアプリケーションを開発していると作成する機能だと思います。
そのファイルダウンロードを単一ではなく、一度に5、10、20ファイルをダウンロードするという要件で悩みまくった末に、行きついたやり方を記載します。
お客様の要望は、「複数(10とか20とか)のファイルを1つずつダウンロードしたい」そう。
(普通、Zipとかにまとめない???)
とか思ったが、お客様の要望を叶えるのも仕事である。
ファイルそのものは既存のドライブを使用して取得する。
始めに考えたのは、DLするファイル分、DL処理を繰り返せばいいだろ、でした。
DL処理を別Functionにしておいて、必要なファイル数分呼び出せばいいと思っていたのです。
だが、実際はFor文をぐるぐる回すと、ループだけ先に動いてしまい、その処理速度にDLが追いつけない、と事象が発生。
テストで10ファイルをDLすると、For文の処理速度とDL処理がうまく追いついた3,4ファイルのみDLされたのだ。
デバックすればもちろん10ファイルがDLされるが、当然顧客自身で処理を止めながら処理を進めてくれるわけではないので、何か別の解決策を講じる必要がある。
・Ajaxを入れ、処理が完了次第、次の処理を実行するソースを入れてみる
・処理を数秒止めてみる
とネットで検索で出てくる方法を試してみるも全くうまくいかず。。。
この「処理が終わってから」というのと、For文で回す、というのがネックだった。
このループこそがうまくいかない原因だった。
そこで、
処理が終わったかどうか、これを判断するのではなく、処理が終わってから処理を開始すればいい。
と発想を変えてみた。
途中処理を止めるのでもなく、処理が終わったかどうかの判断をさせるのでもない。
そのまま処理が終わってから次へ進めるようにすればいいのだ。
結果、再帰処理をしてみたら、これがきれいに指定分のファイルがダウンロードできたのだ!
ちなみに、20ファイルと数を増やしても動いた。
これぞ、発想の転換!
難題が解決したときの解放感というか達成感はいつでもテンションが上がるものだ。
1人だったら叫んでいるところだ。
こうして、複数ファイルを1つずつDLしたい、という顧客の要望を叶えることができた。
もっとも、複数のファイルを1つずつダウンロードするのではなく、Zipなどに圧縮して一度にダウンロードするのが通例である。
今回は、それを提案したうえで、いや、それでも1ファイルずつがいいと顧客の要望を取り入れた形だ。
いろんなシステムを見ていると、「誰だよ!こんな仕組みにしたやつ!!」と叫びたくなるようなものもあるが、要件定義を直接していくと、何もSEやPGの問題ではないのを知る。
お客様のいうことを、なんでも聞いてあげるのが是ではないが、汲み取る努力も必要だ。
そのうえで、いかに運用しやすく、後に負担をかけない仕組みを作るのが課題ではないだろうか?