おさらい(関数ってなんだっけ?)
コールバックって何?
意味わからん! ??????????????????????????????????
なぜコールバックがいるの?
まず「いいプログラミングとは?」という話
いいプログラミングとは?
汎用性が高い
ということ。
「汎用性が高い」っていうのは、「使い回しの効く」「色んな所で使える」という意味。時間かけて作ったプログラムなんだから、色んな所で使えたほうがいいじゃん?
で、この「使い回しの効く」プログラミングのソースコードを書くために必要なのが「コールバック」です。
汎用性の高い関数を実装したい
例えば「順番を並び替える」という関数を実装しようと思います。
「順番を並び替える」なんていう機能はよく使いそう。せっかく作るなら色んな所で使えるように実装したい!
まず、この2つのデータを見てください。
Lemon | まちがいさがし | |
---|---|---|
よみがな | れもん | まちがいさがし |
リリース日 | 2018年3月14日 | 2019年5月14日 |
最高ランキング | 1 | 2 |
では、この2曲を並び替えてください。
となったら、
何順に?
となりますよね?
順番を並び替えるには「何順?」というのがとても重要です。
じゃあ次、
田中 | 鈴木 | |
---|---|---|
年齢 | 28 | 25 |
郵便番号 | 555-0055 | 333-0033 |
では、この2人を並び替えてください。
何順に?
一口に「並び替える」といっても、並び替える対象によって、何順にするのかというのは変わってきます。
でも、「使い回しの効く並び替えの関数」は、使い回しができるので、曲のランキング順であろうと、人の年齢順であろうと、並び替えたいんです。
だって、 使い回しが効く関数だから
で、ここででてきます。「コールバック」
以下は、JavaScriptの配列型の開発ドキュメント
Array.prototype.sort() - JavaScript | MDN
中を見てみると。。。
function compare(a, b) { if (ある順序の基準において a が b より小) { return -1; } if (その順序の基準において a が b より大) { return 1; } // a は b と等しいはず return 0; }
これ要は、aとbどっちが大きいか教えて!というのをコールバックで教えてあげるんです。
- aよりbのほうが小さかったらマイナスの値を返してください
- aよりbのほうが大きかったらプラスの値を返してください
- aとbが等しかったら0を返してください
もし、そういうルールで返してくれる関数を指定してくれたら、こっちで並び替えするよ!という機能が、このsort()という関数
例1 (年齢順に並び替える)
const users = [ { name: "田中", age: "28", postcode: "555-0055" }, { name: "鈴木", age: "25", postcode: "333-0033" } ] users.sort((a, b) => { if (a.age < b.age) { return -1; } if (b.age < a.age) { return 1; } return 0; }) console.log(users)
こうすると、usersという配列をage順に並び替えてくれます
ちなみに、これは以下のように書くこともできます。
users.sort((a, b) => { return a.age - b.age }
こう書いても、aの方が小さいときはマイナスに、aの方が大きい時はプラスに、一緒の時は0になるからですね。
例2 (検索)
次はfindというメソッドを使ってみます。findは配列から条件に当てはまるものが見つけるという関数です。配列から見つける。なんていう機能も使いまわしできるように作りたいですよね!
Array.prototype.find() - JavaScript | MDN
今度はこう書いています。
find メソッドは、配列のそれぞれの添字に対して一度ずつ、 callback 関数を実行し、 callback 関数が truthy な値を返すまで繰り返します。その場合、 find は直ちにその要素の値を返します。そうでなければ、 find は undefined を返します。
???
よくわからないですね。これは「見つけたい条件に一致したらtrueを返してね」ということです。
曲の情報が入っている配列からrankが1のものを取得するためには以下のように書きます。
const songs = [ { title: "Lemon", kana: "れもん", releaseDate: "2018/3/14", ranking: 1 }, { title: "まちがいさがし", kana: "まちがいさがし", releaseDate: "2019/5/14", ranking: 2 } ] const rank1song = songs.find((song) => { return song.ranking === 1 }) console.log(rank1song)
課題1.
与えられた曲データをプレー回数が多い順にソートし、以下のフォーマットで表示してください。
結果
問題ダウンロード
curl -o prog-ac.zip -fsSL https://assets.prog-ac.jp/lessons/ranking.zip && unzip ./prog-ac.zip && rm ./prog-ac.zip
課題2.
コマンドライン引数で渡された秒数後に"DONE"と表示するタイマーを作ってみよう
ヒント:setTimeout() というメソッドをつかいます
Timers | Node.js v14.3.0 Documentation
問題ダウンロード
curl -o prog-ac.zip -fsSL https://assets.prog-ac.jp/lessons/ranking.zip && unzip ./prog-ac.zip && rm ./timer.zip
まとめ
今後みなさんが本格的なアプリ開発を始めた時に、ボタンが押された時、データ通信が終わった時…など、コールバックを使うことがとても多くなります。
コールバックの考え方は、基本的には、使うライブラリや関数側から「これどうする?」と教えて欲しいときに使います。
難しく考えすぎずに、「あーそれはこう処理しておいてー」と関数で実装して返してあげましょう。