例えばこんなコード。
loadCompletions: ->
fs.readFile(
path.resolve(__dirname, '..', 'completions.json'),
(err, data) => @completions = JSON.parse(data) unless err?)
初心者はここに違和感を感じる
(err, data) => @completions = JSON.parse(data) unless err?
こんな説明はヤダ。
ググればすぐ出てくるよ。⇒本当に?
これは非同期で読み込んで引数にコールバック関数を指定しているんだよ。⇒はぁ?
javaから学び、直したほうがいいよ。⇒知らないし・・。
私ならこう説明されたい。
ポイントは2つあって「非同期、コールバック」なんだけど、聞いたことある?
このreadFile関数は非同期で実行されるように設計されているんだ。
例えば重たいファイルがあって、それを全部読み取らないと、次の画面に行ってくれないアプリだったら、ユーザーはイライラしてしまうだろ?そーゆうのを避けるために、非同期っていう思想があるんだ。
全部読み取らなくても、次に進むってことね。それを可能にするためにコールバックっていう概念があるんだ。
さっきの例で言ったアプリの場合だと、全部読み取らないで次の画面を出したら、動いている処理は、二つあることになるよね。
1、ファイル読み取り中⇒読み取り終了に向かう処理
2、ユーザーに次の画面を見せる処理
じゃデータ読み込み中はユーザーに画面見せて、他の事してもらうことにしよう。
それも終わって次の画面出したいけど、次に行くにはどうしてもさっき読み込み中だったデータが必要ってときはどうする?
画面をまた前に戻す。なんてしてたら、マジ切れされちゃうよね。
そうじゃなくて読み込み中の処理が全部終わったら、読み込んだデータを、次の画面に送るような機能をつければいいよね。
そうやって、非同期で実行された処理が終了した時点で実行する処理の事をコールバックっていうんだ。
プログラムでいうこれがその部分だよ。
(err, data) => @completions = JSON.parse(data) unless err?
今回は、unless err?でエラーがないかチェックして、JSON.parse(data)の結果を、loadCompletionsメソッドの外側にあるcompletions変数に格納しているよ。
(err, data)
このerrとdataはどこから来たかも気になるよね。
それはreadFile関数が、ファイルを読み取ったデータをdataに、エラーが出たらerrに入れてくれるんだよ。
まだ、あまり馴染みがない形かもしれないけど、関数自体が、結果を引数に入れて、さらにそれを引数である、コールバック関数に渡す形は、非同期処理によく出てくるから覚えておくといいよ。
あと、completionsの前についている「@」が、気になる?javaScriptのthisって言えばすぐわかるかな?
「->」じゃなくて「=>」なのが気になるなら、メソッド⇒関数⇒関数って構造が入れ子になっていくと、thisの状態も所々で変わってくるんだ。「=>」はそれを防ぐんだ。つまり前のthisを引き継いでいるって考えて。
で結局どうしてほしいかって?
1、目的を伝えてほしい。
なぜそれが必要になるのか、どうしてその形にしているのか。理解すると人は応用できるようになる。
2、例えてほしい。
とても難しい概念でも、だいたいは身近なもので置き換えることができる。そうすれば人は容易に理解できるようになる。
3、実際に示してほしい。
コードのどの部分がそーゆう意味なのか、視覚に訴えて示してくれると、印象に残る。
4、それでもう一度詳しく説明してほしい。
そうすれば、要点が繰り返され、記憶に刻まれる。
5、察してほしい。
上級者は初心者がどんな分野でつまずくのか、知見があるはず。自分も初心者だったのだから。それを活かしてほしい。でも質問する側にも問題がある。自分がどこが分かっていないのかさえわからないようでは絶望的。でもどこがわからないのか親切に聞きだしてくれたら、初心者にとってはありがたい事に変わりはない。
6、考えさせる。
説明を受け身になっているだけだと、思考は停止する。本来人の思考速度はとても速いのだ。それを止めてはいけない。適切な質問をして考えを確認し、思考を導けば良い結果につながる。