1. 程式人生 > >nodejs 中的異步之殤

nodejs 中的異步之殤

不能 成功 但是 scope express mod 發現 HR mysq

nodejs 中的異步之殤

終於再次回到 nodejs 異步中,以前我以為異步在我寫的文章中,已經寫完了,現在才發現,還是有很多的地方沒有想清楚,下面來一一說明。

模塊同步與連接異步

大家應該,經常使用 express 進行網站開發。express 本來的問題不是重點,你肯定要用到第三工具,redis, mysql 了之類的。

redis 需要連接,而連接成功需要一個回調(他是一個異步)。問題就在這裏,這個問題是:倒底是 redis 先連接成功,還是 express 先啟動成功?

redis.on('ready', cb);

app.listen(300, cb);

哪個先成功?如果你認為我的問題不太明白,我們把 redis 的準備成功的時間拉長,變成 10 分鐘,這樣你就看出來了, redis 還沒有準備好, express 就運行了,網站成功運行了。如果 redis 是緊緊做為緩存還好,如果是一些有用的數據,那可能就會有用戶不可以訪問網站,你可以把 redis 換成別的組件,就是說 nodejs 中的異步已經影響到了組件中,但是你還是按同步的思路去使用,去引用。

這就需要有說明,組件的啟動順序,保證組件連接正常,才能啟動網站。

從根上進行控制

從哪裏處理呢?

我認為還是要從根上進行處理, nodejs 中的異步不能保證順序,不能保證你放在前面的代碼就一定在前端運行。你需要的是從根上描述你的模塊的依賴和啟動順序,這樣就能保證網站的可用性。

但這樣寫可以嗎?


redis.on('ready', () =>{
    app.listen(300, cb)
})

可以是可以,但是你不覺得很難受嗎?

因此,我的做法,所以有模塊的啟動順序,都要用一個函數說明,保證啟動順序和依賴,這樣裏我用是的 async.auto 模塊,他能顯式說明函數的順序:

const async = require('async')

function main() {
  async.auto({
    config(cb) {
      cb(null, require('./config'))
    },
    logger: ['config', (scope, cb) => {
      const logger = require('./module/logger')(scope.config)
      cb(null, logger)
    }],
    redis
: ['config', (scope, cb) => { const redis = require('./module/redis') cb(null, redis) }], util(cb) { cb(null, require('./module/util')) }, module: ['util', 'logger', 'redis', (scope, cb) => { cb() }], web: ['config', 'module',(scope, cb) => { const web = require('./web')(scope, cb) }], ready: ['module', 'web', (scope, cb) => { cb() }] }, function(err, scope) { const logger = scope.logger logger.info('app running') }) } main()

這就是我的函數, web 模塊也是組織進來,這樣就可以在 web 啟動時,第三方的模塊都準備好。

想通了這點,我把我自己的項目重寫了一遍,歡迎圍觀:

express-boilerplate

nodejs 中的異步之殤