• nodejs 中的异步之殇


    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

  • 相关阅读:
    【SignalR学习系列】3. SignalR实时高刷新率程序
    【SignalR学习系列】4. SignalR广播程序
    【SignalR学习系列】5. SignalR WPF程序
    python gb2312 转换为 utf-8
    爬虫 需要什么样的 CPU,内存 和带宽
    TypeError: sequence item 0: expected string, Tag found
    MySQL 数据的 截取,数据清洗
    MySQL (1366, "Incorrect string value: '\xF0\x9F\x8E\xAC\xE5\x89...' for column 'description' at row 1")
    微博爬虫 ----- 微博发布时间清洗
    ReferenceError: weakly-referenced object no longer exists Python kafka
  • 原文地址:https://www.cnblogs.com/htoooth/p/9057413.html
Copyright © 2020-2023  润新知