2017-12-09 3 views
1

問題は次のとおりです。これは私が問題に使用することを決定し、それが全体的な実装を向上させることができれば変更することができるデータ構造であることがこのネストされた非同期ループを改善するにはどうすればよいですか?

let myObj = [ 
{'db1':['doc1','doc2','doc3']}, 
{'db2':['doc4','doc5']}, 
{'db3':['doc7','doc8','doc9','doc10']} 
] 

注:私はそうのようなオブジェクトの配列を持っています。実際のdbとdocのIDは、以下のようにフォーマットされたテキストファイルから読み込まれます。

"db1","doc1" 
"db1","doc2" 
... 

私のアプリは同期してdbリストを繰り返します。それぞれのdb反復の中には、文書リストの非同期反復があります。各文書は検索され、処理され、dbに保存されます。

基本的にどのインスタンスでも:1つのデータベースですが、複数のドキュメントです。

dbIterator:DBSを反復する同期アウターループ

私はそうのような上記の作業実装を持っています。 docIteratorに渡されたコールバックは、次の繰り返しをトリガーします。

const dbIterator = function (x) { 
    if (x < myObj.length) { 
    let dbObj = myObj[x]; 
    let dbId = Object.keys(dbObj)[0]; 
    docIterator(dbId, dbObj[dbId],()=>merchantIterator(x+1)); 
    } else { 
    logger.info('All dbs processed'); 
    } 
}; 

docIterator:ドキュメントを反復処理する非同期ループ。コールバックcbは、すべての文書が処理された後に呼び出されます。処理し、個々の文書を保存するために使用さ:これはdocsProcesseddocsToBeProcessed変数

const docIterator = function(dbId, docIds, cb){ 
    //create connection 
    targetConnection = //some config for connection to dbId 
    let docsProcessed = 0; 
    let docsToBeProcessed = docIds.length; 

    //asynchronous iteration of documents 
    docIds.forEach((docId)=>{ 
    getDocument(docId, targetConnection).then((doc)=>{ 
     //process document 
     processDoc(doc, targetConnection).then(()=>{ 
     //if processing is successful 
     if (++docsProcessed >= docsToBeProcessed) { 
      cb(); 
     } 
     }) 
     //if processing fails 
     .catch((e) => { 
     logger.error('error when processing document'); 
     if (++docsProcessed >= docsToBeProcessed) { 
      cb(); 
     } 
     }); 

    }).catch((e)=>{ 
     logger.error('error when retrieving document: '); 
     if (++docsProcessed >= docsToBeProcessed) { 
     cb(); 
     } 
    }); 
    }); 
}; 

processDocを経由して追跡されます。これは、文書の処理が行われたときにターン単位でdocsProcessedと条件付き(docsProcessed >= docsToBeProcessed)がコールバック予想通りこれは動作しますが、私のために、この実装は次善であるdocIterator

const processDoc = function(doc, targetConnection) { 

    return new Promise(function(resolve, reject) { 
    if(shouldThisDocBeProcessed(doc){ 
     let updatedDoc = logic(doc); 
     targetConnection.insert(updatedDoc, updatedDoc._id, 
     function (error, response) { 
      if (!error){ 
      logger.info('updated successfully'); 
      } else { 
      logger.error('error when saving doc'); 
      } 
      resolve(); 
     } 
    ); 
    } else { 
     resolve(); 
    } 
    }) 
}; 

に渡さ呼び出す解決さ約束を返します。厄介な。私はこれを改善することができ、最も重要なのは、同期と非同期の問題に対する解決策をよりよく理解し実装することができると確信しています。

私は建設的な批判に開放されています。だからこれはどのように改善することができますか?

+0

コードレビューのための良い場所はhttps://codereview.stackexchange.com/です。これを策定するのに費やした時間と労力のために投票してください。 –

+0

それは 'docs'か' docIds'ですか? – Bergi

+0

約束をしているので、 'docIterator'関数でコールバック引数を使わないでください。代わりに約束を返す!また、自分で数えるプロセスをすべて行う必要はありません。単に 'Promise.all'を使用してください。 – Bergi

答えて

0

多分このような何か?

スロットルの実装例はhereです。

//this should be available in both modules so you can filter 
const Fail = function(details){this.details=details;}; 
// docIterator(dbId,docIds) 
// .then(
// results =>{ 
//  const failedResults = results.filter(
//  result => (result&&result.constructor)===Failed 
// ); 
//  const successfullResults = results.filter(
//  result => (result&&result.constructor)!==Failed 
// ); 
// } 
//) 

const docIterator = function(dbId, docIds){ 
    //create connection 
    // targetConnection = //some config for connection to dbId 
    let docsProcessed = 0; 
    let docsToBeProcessed = docIds.length; 
    //asynchronous iteration of documents 
    docIds.map(
    docId => 
     new Promise(
     (resolve,reject) => 
      //if you use throttled you can do: 
      // max10(
      // ([docId,targetConnection])=> 
      //  getDocument(docId,targetConnection) 
      //)([docId, targetConnection]) 
      getDocument(docId, targetConnection) 
    ) 
     .then(
     doc => 
      //if this returns nothing then maybe you'd like to return the document 
      processDoc(doc, targetConnection) 
      .then(
      _ => doc 
     ) 
    ) 
     .catch(
     err => new fail([err,docId]) 
    ) 

) 
}; 
関連する問題