nodejs是同步还是异步

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了nodejs是同步还是异步相关的知识,希望对你有一定的参考价值。

node里几乎所有用到回调函数的地方,都是异步的,回调函数后面的代码很可能比回调函数中的代码后先执行,特别是数据库操作。当然,node也提供了同步版本的函数,例如文件操作,fs.readFileSync()是fs.readFile()的同步版本。

那么问题来了,forEach()是不是异步的呢?按理说,没有加Sync,应该是异步的呀。

复制代码 代码如下:

var arr = [\'a\', \'b\', \'c\'];
var str = \'123\';
arr.forEach(function(item)
str += item;
while (true) ; //用一个死循环,卡死它~~
);
console.log(str);

运行上面的代码,结果它就这么卡死了,没有任何输出。。

所以说,node里的forEach()是同步的!!

第一次用node的时候,没有考虑过这个问题,按同步的写了,写突然想到,测试后虚惊一场,以为以前的代码都写错了。
参考技术A

既可以同步也可以异步

同步:

var fs = require("fs");var data = fs.readFileSync('input.txt');console.log(data.toString());console.log("程序执行结束!");

异步:

var fs = require("fs");fs.readFile('input.txt', function (err, data) 
    if (err) return console.error(err);
    console.log(data.toString()););console.log("程序执行结束!");

参考技术B 很经典的异步

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

以上是关于nodejs是同步还是异步的主要内容,如果未能解决你的问题,请参考以下文章

Node js中Promise是同步还是异步

Javascript 默认是同步(阻塞)还是异步(非阻塞)

node.js里的forEach也是异步的吗

nodejs 中的异步之殇

Django是同步的还是异步的?

Nodejs密集型CPU解决方案