2017-08-07 6 views
0

NodeJS 6.9.3非同期NodeJSでガード句とデータベース呼び出しを結合する方法

PHPやRubyなどの同期言語で作業しているとします。私たちはしばしば、このパターンを見るでしょう:

$all_results = []; 
$array_of_words = get_relevant_words(); 

for ($i=0; $i < count($array_of_words); $i++) { 

    $word = $array_of_words[$i]; 

    if (len($word) < 3) { 
     continue; 
    } 

    $results = database_call($word); 
    $all_results = array_merge($all_results, $results);  
} 

は、アレイの上にループデータベース呼び出しを行うと、時折、特定の呼び出しをスキップするコードを強制的にいくつかのガード条項を持つ - これは標準パターンである、あなたはほぼでそれを見つけますすべてのコードベース。

NodeJSは非同期なので、特定の種類の制御フローをあきらめて、それらを元に戻す必要があります。

私は先週、この問題に取り組んできましたが、これをどうやって行うのかほとんど考えましたが、私のコードは非常に醜いので、これを行うにはもっと慣用的な方法が必要ですNodeJSにあります。私は慣用的なアプローチは何か不思議ですか?

return database_queries.profiles(word, array_of_words_from_string_from_api_call, index_to_read, map_of_profiles) 
     .then(function(results_from_database) { 

      map_of_profiles = Object.assign(map_of_profiles, results_from_database); 

      if (index_to_read < array_of_words_from_string_from_api_call.length - 1) { 
       return database_queries.profiles(word, array_of_words_from_string_from_api_call, index_to_read + 1, map_of_profiles); 

      } else { 
       return map_of_profiles; 
      } 

この関数は、インデックスが配列の最後の項目に到達するまで自身を呼び出し続けます:

は今、代わりにループの、私は再帰的コールバックを持っています。

データベースクエリ機能の内部では、私は私のガード句を持っている:私のコードは本当に醜い得るために始まる

  if (!search_term || search_term == "") { 
      var thenable = { then: function(resolve) { 
      return new Error ({ 
           "message" : "The search term was empty so we did not run the database query.", 
           "array_of_words_from_string_from_api_call" : array_of_words_from_string_from_api_call, 
           "index_to_read" : index_to_read, 
           "map_of_profiles" : map_of_profiles 
           }); 
      }}; 
      return thenable; 
      } 

これがある:私は返すことができるだけのようなarray_of_words_from_string_from_api_callなどの変数に渡していますそれらはエラーになります。このエラーをキャッチするcatch()ブロックで利用できるようになります。

私のcatch()ブロックを使って実際のエラーを処理するのではなく、上記のすべての再帰的コードを複製しました。これはdatabase_queries.profiles()を呼び出し続けます。

従来のガード句を模倣するためにエラーを返す方法がありました。私がこのエラーを処理できる唯一の場所はキャッチブロックです。

NodeJSでこれを行う方法はあまり醜いものでなければなりません。誰でも慣用的なアプローチが何であるか教えてもらえますか?

+0

は 'async'を使用し、' async.eachLimit'です。あなたが大量のアイテムを持っている場合、 'parallel'はお勧めできません。ネットワーク、db load、' parallelLimit'、 'eachLimit'を使い、一度に5つの操作を定義してください。 – num8er

答えて

2

1つの可能性は、非同期ライブラリを使用することです。非同期コードを並列または定義された順序で実行できます(呼び出しが相互に依存する場合)。 あなたがasync.each eachを使用することができ、それが並列に配列内のすべての要素にあなたの関数を実行し、最終的には、最終的なコールバックを呼び出しますあなたのケースではasync documentation

を見てみましょう。

eachLimitを使用することをお勧めします。これにより、多くのリクエストでDBがクラッシュしないように、並列リクエストの数を制限できます。

const processWords = (words, done, limit = 5) => { 
    const results = []; 
    async.eachLimit(
    words, // iteratable variable 
    limit, // concurrency limit 
    (word, next) => { // item processor 
     if (word.length < 3) { 
     return next(); 
     } 

     database_call(word, (error, result) => { 
     if(error) return next(error); 
     if(result) results.push(result); 
     next(); 
     }); 
    }, 
    error => done(error, results) // at the end of iteration 
); 
}; 

const words = ['hello', 'world']; 
processWords(words, (error, result) => { 
    console.log(error, result); 
}); 
関連する問題