2012-01-13 17 views
2

別の非同期の内部で非同期メソッド呼び出しを行う方法eachメソッド(NodeJS)?別の非同期 `each`メソッド(NodeJS)の内部で非同期メソッド呼び出しを行う方法は?

具体的な例 - データベースを使用して、すべてのレコードを削除する必要があります。 しかし、私はコレクション全体を削除することはできません、私はレコードを読んで、アプリでいくつかのビジネスロジックを実行し、それだけを削除する必要が削除前に、1つずつすべてのレコードを破壊する必要があります。

それでは、私たちのdeleteAllメソッドを実装してみましょう(実際には、ノードMongoDBのネイティブドライバからの実際のAPIです):それを行うための方法、実際に

deleteAll = function(selector, callback){ 
    collection.find(selector).each(function(err, doc){ 
    if(err){ 
     callback(err) 
    }else{ 
     if(doc === null){ 
     // each returns null when there's no more documents, we are finished. 
     callback(null)  
     }else{ 
     doSomeBusinessLogicBeforeDelete(doc) 

     // How to delete it using asynchronous `remove` method?   
     collection.remove({_id: doc._id}, function(err){ 
      // What to do with this callback? 
      // And how to make `each` wait untill we 
      // deleting this record? 
      ??? 
     }) 
     }  
    } 
    }) 
} 

あります

- collection.nextObjectメソッドを使用しての代わり collection.eachは、私が知りたいのは、 eachを使ってこれを解決できるかどうかです。今は可能ではないと信じていますが、間違っているかもしれません。

UPDATE:まあ

Cursor.prototype.each = function(callback) { 
    var self = this; 

    if (!callback) { 
    throw new Error('callback is mandatory'); 
    } 

    if(this.state != Cursor.CLOSED) { 
    process.nextTick(function(){ 
     // Fetch the next object until there is no more objects 
     self.nextObject(function(err, item) {   
     if(err != null) return callback(err, null); 

     if(item != null) { 
      callback(null, item); 
      self.each(callback); 
     } else { 
      // Close the cursor if done 
      self.state = Cursor.CLOSED; 
      callback(err, null); 
     } 

     item = null; 
     }); 
    }); 
    } else { 
    callback(new Error("Cursor is closed"), null); 
    } 
}; 
+0

'each'メソッドのソースコードはありますか?あなたがそれを持っているなら、あなたを見つけることは非常に簡単です。 – hugomg

答えて

0

あなたが書いたことは、この行についてはよく分からないが、動作します:eachメソッドのソース

if(doc === null){ 
    // each returns null when there's no more documents, we are finished. 
    callback(null) 

私はロジックを知らない、ので、しかしそれはうまくいくでしょう。技術的には、関数は待たずに、別の関数を渡すだけで、作業が終わったときに実行されます。何が行われているのかはここでは非同期で平行です。 asyncモジュールでは、それぞれの非同期バージョンとその他の機能を見ることもできます。

+0

ええ、それはうまく動作しますが、 'collection.remove'は直列ではなく並列で実行され、' collection.remove 'のいくつかが終了する前にファイナルコールバックが起動する可能性があります。 –

1

このようなものを試してみてください。

deleteAll = function(selector, callback){ 
    // count all documents you need to fire remove for 
    var count = collection.filter(function(doc) { return doc === null }).length, 
      i = count; 

    collection.find(selector).each(function(err, doc){ 
    if(err){ 
     callback(err) 
    }else{ 
     if(doc === null){ 
     callback(null)  
     }else{ 
     doSomeBusinessLogicBeforeDelete(doc) 

     collection.remove({_id: doc._id}, function(err){ 
      i--; 
      if (i <= 0) callback('done'); 
     }) 
     }  
    } 
    }) 
} 
1

ので、ノードと数ヶ月後、私は私の質問に対して答えてしまった、ここでは各非同期の一つの可能​​な実装は、(そこに似た他のことが、エラー処理に若干の違いがあります)です。

​​

mongoのeachの実装が異なっています。適切な順次反復を行うことは不可能です(おそらく、異なる設計目標を念頭に置いても大丈夫かもしれません)。

関連する問題