2015-02-09 109 views
0

我正在編寫一個NodeJS腳本,它將通過Heroku的調度程序每小時運行一次。我在咀嚼我擁有的Mongo實例(mongohq/compose),然後用這些結果做一些事情。我正在使用Mongoose.js和find()命令。這將返回一組結果。有了這些結果,我需要執行額外的查詢以及一些額外的異步處理(發送電子郵件等)。貓鼬查找結果和異步

長話短說,由於節點的異步性質,我需要等到所有處理完成後再致電process.exit()。如果我不提前停止腳本,並且整個結果集都沒有處理。

問題是,在這一點上我有聖誕節電話的呼叫(5嵌套asnyc電話)。

通常情況下,我會用async.js庫解決這個問題,但我遇到了一個問題,通過這麼多的回調來看待這個問題。

如何在退出腳本之前確保完成整個過程?

下面是我的工作的代碼(注:也使用下面lodash爲_):是什麼使你的代碼混淆的

Topic.find({ nextNotificationDate: {$lte: moment().utc()}}, function (err, topics) { 
    if (err) { 
     console.error(err); 
     finish(); 
    } else { 

     _.forEach(topics, function (topic, callback) { 

      User.findById(topic.user, function (err, user) { 
       if (err) { 
        // TODO: impl logging 
        console.error(err); 
       } else { 

        // Create a new moment object (not moment.js, an actual moment mongoose obj) 
        var m = new Moment({ name: moment().format("MMM Do YY"), topic: topic}); 
        m.save(function(err) { 
         if(err) { 
          // TODO: impl logging 
          console.error(err); 
         } else { 

          // Send an email via postmark 
          sendReminderTo(topic, user, m._id); 

          // Update the topic with next notification times. 
          // .. update some topic fields/etc 
          topic.save(function (err) { 
           if(err) { 
            console.error(err); 
           } else { 
            console.log("Topic updated."); 
           } 
          }) 
         } 
        }) 
       } 
      }); 
      console.log("User: " + topic.user); 
     }); 
    } 
}); 
+0

如何是 「電話聖誕樹效應」(又名[回調地獄(http://google.com/search?q=callback+hell))使得「過程沒有完成之前退出「?或者他們是兩個單獨的問題? – laggingreflex 2015-02-09 16:25:20

+0

或多或少只是幫助理解問題。回調地獄正在導致我過度渴望/不明白如何解決它。 – 2015-02-09 17:21:53

回答

0

部分是else語句的使用。如果您返回錯誤,則不需要else語句,併爲每個回調保存4行縮進。這本身將使事情變得更加可讀。

使用異步:

Topic.find({nextNotificationDate: {$lte: moment().utc()}}, function (err, topics) { 
    if (err) { 
     console.error(err); 
     return finish(err); 
    } 

    async.each(topics, function(topic, topicCallback) { 

     async.auto({ 

      user: function (callback) { 

       User.findById(topic.user, callback); 
      }, 

      moment: function(callback) { 

       var m = new Moment({name: moment().format("MMM Do YY"), topic: topic}); 
       m.save(callback); 
      }, 

      topic: ["moment", "user", function (callback, results) { 

       var m = results.moment; 
       var user = results.user; 

       sendReminderTo(topic, user, m._id); 
       topic.save(callback); 
      }] 

     }, function(err) { 
      if (err) { 
       return topicCallback(err); 
      } 

      console.log("Topic updated.") 
      return topicCallback(); 
     }); 
    }, function(err) { 
     if (err) { 
      console.error(err); 
      return finish(err); 
     } 

     return finish(); 
    }); 
}); 
+0

不錯。謝謝。然而,我後面的最終結果是如何執行一切,然後完成,知道何時調用process.exit()。 :) – 2015-02-09 18:21:55

+0

@ DMcCarthy承諾。 https://github.com/kriskowal/q#combination – Tony 2015-02-09 20:33:05

+0

@Tony - 這就是我傾向於,但不能肯定如果這會爲我做。 – 2015-02-09 20:43:54