質問: getAllQuery(TABLE_ACCOUNT_LIST); ``` いろいろと調べてはいるのですが、調べ方のとっかかりがなく困っています。 どのように関数を改変すれば良いか教えていただけないでしょうか。
回答: Javascriptでは、外部とのI/Oがある場合、非同期に処理する必要があります。まれに同期的な関数が用意されている場合もありますが、基本的には、コールバック関数によって、「非同期にデータを受け取らなければならない」と思ってください。 従いまして、残念ながら、 ``` var result = getAllQuery(TABLE_ACCOUNT_LIST); ``` のように呼び出すことはできません。livetc様の回答のように ``` getAllQuery(table_name, callback){ // 処理 callback(data['Items']); } ``` というようにサブルーチンを作成し、呼び出し側も ``` getAllQuery(TABLE_ACCOUNT_LIST, function (result) { // result 受け取り後の処理 }); ``` と書くようにする必要があります。これがコールバック地獄と呼ばれており、この function のネストが深くなりすぎないようにする技がいろいろとありますので、「Javascript コールバック地獄」などで検索してみてください。 参考:Node.jsのコールバック地獄をPromiseやGeneratorを使って解消する ### コールバックによる非同期動作について 他の回答へのコメントを見ていて、コールバックによる非同期動作について解説する必要があるかと思い、追記します。 もとのコードの`dynamodb.scan` を呼び出した時、この API はその終了を待たずに帰ってきます。 すると、getAllQueryの実行自身も終了し、 `function (err, data) {}`で記述した内容は実行を保留された状態になります。この保留された内容はプログラム全体が終了まで実行されません。したがいまして、 ``` var result = getAllQuery(TABLE_ACCOUNT_LIST); // result を参照する処理 ``` と書きたくても、 result に結果を入れることは不可能なのです。一旦、プログラムを終了すれば、保留されていたコールバック(`function (err, data) {}`で記述した内容)が実行されます。そして、そこから新たな旅を始めなければなりません。 node.js はシングルスレッドで動作しており、 1. 読み込んだプログラムの実行 2. 保留されたコールバックのうち、実行可能なもの(I/Oが終わったもの)を一つ選び実行 3. 2.を繰り返し、保留されたコールバックがなくなるとプロセスを終了 という処理を行います。シングルスレッドであるため、I/O ごとにスレッドの実行を保留することは性能上許されません。そのかわりにマルチスレッドプログラミングのように微妙なタイミングを考えてmutex を使ったりする必要が無いわけです。