nodejs 这类异步为主导的程序里会出现 callback hell,这里我用 Java 写了一段 callback 嵌套的代码来类比 nodejs
这里的三个嵌套是因为后一个依赖前一个的结果,那么这三个操作应该是不能并行的,所以 nodejs 写出了嵌套代码,那么问题是这种情况下异步式的代码不比同步的代码性能好吧?感觉业务上蛮多都是后一个依赖前一个,并行度并不高,引入异步编程会不会收益不大?
client.getConnection(res -> {
SQLConnection connection = res.result();
connection.query("SELECT count(1) FROM T_User", res2 -> {
connection.query("SELECT count(1) FROM T_Book", res3 -> {
System.out.println(res2.result().getRows() + "--" + res3.result().getRows());
});
});
});
同步写法
SQLConnection connection=client.getConnection();
data1=connection.query("SELECT count(1) FROM T_User");
data2=connection.query("SELECT count(1) FROM T_Book");
1
Xrong 2017-09-01 11:51:39 +08:00
个人愚见:楼主的例子本身就看不出引入异步编程的好处,只是纯粹为了达到同步效果而不得以采用的写法而已。当然你可以用些 async 之类的库,假装看上去是同步的样子。
|
2
jarlyyn 2017-09-01 11:53:33 +08:00
楼主需要了解 async 或者 promise
还有 co 库。 还是嫌麻烦不妨看看 go 之类的语言。 |
3
keenwon 2017-09-01 11:59:17 +08:00
nodejs 是单线程,异步非阻塞的
也就是说,三个嵌套的异步请求,有依赖关系,不是每有意义的,意义就在于第一个请求还未执行完的时候,线程空闲下来可以接受新的请求,或者继续执行其他同步代码,而不需要阻塞在哪里傻傻的等 至于 callback hell,楼上说的 async/await,co 等都可以解决 |
4
seki 2017-09-01 12:01:44 +08:00
前后依赖的本来就不是能并行的。可以并行的是你有多个不互相作用的任务的时候,可以一起执行
|
5
twogoods OP @keenwon 我是一个 Java 程序员,一直以来都是同步的方式写代码,Java 本身是多线程的 [线程空闲下来可以接受新的请求] 这个在 Java 里根本不是问题,所以我会有疑问,异步编程在 Java 里的适用场景
|
6
a7063888 2017-09-01 12:06:16 +08:00 via iPhone
确实不大
|
7
twogoods OP @keenwon 再多问一句,你们 node 里 callback 嵌套或者说 async/await 这种用的多吗?用的多是不是也说明并行度不高,异步最大的好处体现的不多?
|
8
chmlai 2017-09-01 12:10:57 +08:00
你整个系统又不是只有这个三个操作在跑.
|
10
gzlock 2017-09-01 12:22:52 +08:00 via Android
node 都 8 了还 hell 是多闭塞?鼻塞可以治疗,闭塞别人可帮不了你
|
11
bazingaterry 2017-09-01 12:23:08 +08:00 via iPhone
@twogoods JS 天生就几乎没有阻塞的操作,网络请求大多都是异步进行的。
|
12
keenwon 2017-09-01 12:44:07 +08:00 1
@twogoods
1、用的多 2、不是。单线程模型,异步的好处是很大的。 在 node 主线程里,异步不代表并行,而是同一时间只做一件事,要么发起异步操作,要么执行异步操作的回调(有单独的线程检查异步是否执行完成,而且异步回调的执行只有等主线程空闲下来才行,所以 setTimeout 1ms 不一定是 1ms 后立刻执行)。并不是同时在做两件事,如果要真正的并行,可以启动子进程或者使用集群。 所以 node,nignx 这样的东西,利用异步可以以极低的资源占用,处理大量的请求,不需要每请求每进程(线程) 不知道我说清楚了没。写多了同步代码,可能一下子确实不太好理解 js 的异步。 |
13
SuperMild 2017-09-01 12:56:00 +08:00 via iPhone
网页需要非常强的容错能力,以便任何一步有问题,网页都不会卡住不动,所以 JS 天生异步。而 web server 是短时间内接受大量请求的典型场景,用单线程异步的语言可以轻易地提高效率,所以 node 的作者选择了 JS。可见,不是为了异步而异步,是有原因的。
|
14
momocraft 2017-09-01 13:01:56 +08:00 1
并没有什么因素让异步自带性能好,js 那么多异步最初只是因为一线程的不得已。
在这个比较中影响性能的不是 api 形式,是下面的 io 阻塞等因素。如果你把这份 java 代码写成 cps 变换那个样子,看上去就和异步 API 差不多,但是不要期待运行会变快。 |
15
leonlu 2017-09-01 13:07:31 +08:00
LZ,现在你可以在 js 里边这么写了:
let connection= await client.getConnection(); data1=await connection.query("SELECT count(1) FROM T_User"); data2=await connection.query("SELECT count(1) FROM T_Book"); 如果 data1 和 data2 没有啥前后依赖,你可以非常容易地做成并发 io: let connection= await client.getConnection(); let [data1, data2] = await Promise.all([ connection.query("SELECT count(1) FROM T_User"), connection.query("SELECT count(1) FROM T_Book") ]); 是不是和 Java 一样好写了。。。 |
16
aliuwr 2017-09-01 14:35:24 +08:00
异步和并行是两个概念。
|
17
autoxbc 2017-09-01 14:53:05 +08:00
异步并不是一种处理问题的技巧或者方法
而是一种对流程的更高层面的抽象 世界模型本质是异步的 描述世界的语言与这个模型越接近 就越精确自然高效 |
18
zhicheng 2017-09-01 22:30:54 +08:00
异步是用来解决 IO Bound 类型的应用。无法解决 CPU Bound,甚至会多些一举。
详细可以仔细看下我的文章。 https://www.textarea.com/zhicheng/yong-python-lijie-fuwuqi-moxing-shang-566/ https://www.textarea.com/zhicheng/yong-python-lijie-fuwuqi-moxing-xia-596/ |