如图 测试发现如果query.exec()中执行耗时的操作,基本上等于没有异步处理,一个请求需要10秒,两个请求就需要20秒。 这是为什么?
异步接受io请求,后台同步处理?
async.series就是顺序执行的啊,一个执行完成后才执行下一个,所以时间会累加起来:
Run the functions in the tasks array in series, each one running once the previous function has completed.
摘自github的说明:https://github.com/caolan/async#seriestasks-callback
@crystaldust 他这儿是一个function里面
@20082496 嗯,不好意思没看仔细。但是这样的话,执行整个流程,10秒应该就结束了。楼主你说的“两个请求就需要20秒”是指什么情况呢?
@crystaldust 比如说同时发起3个请求,这里有个10秒的等待,第一个请求是10秒后获取到数据,第二个请求就是20秒后获取到数据,第三个就是30秒。就是这样
@20082496 按理说10个并发就是10个请求每个都要等十秒,但是这里是需要累加等待的,10,20,30… 最后一个是100秒后才能拿到数据。
@cheergoh 楼主你的代码提炼一下是不是这个意思:
var async = require( 'async' );
function api( callback ) {
async.series( {
one : function( cb ) {
setTimeout( function() {
cb( null, 'hello' );
} , 10000 );
}
}, function( err, result ) {
callback( result );
} );
}
// Call the API 3 times
var n = 0;
var start_ms = new Date().getTime()
for(var i=0; i<3; ++i ) {
api( function( result ) {
console.log( result );
if( ++n >= 3 ) {
console.log( 'ms: ', new Date().getTime() - start_ms );
process.exit( 0 );
}
} );
}
我这测试最终打印的时间是10031毫秒,结果和预期的10秒是一致的啊
@cheergoh 请求不是并发的么,为什么会顺序…
@20082496 如果真是这样,他怎么做到的…
@crystaldust 可能是我的写法有问题啊 , 发给你看看
@DevinXian 是并发的啊,但是服务器接受到请求总会有先后,发了截图了,可能是我用时间的关系
@cheergoh 我的神哪,sleep!CPU都在sleep中煎熬…
setTimeout会占用cpu,导致事件轮询阻塞
楼主应该没搞清楚async是用来干嘛的。。。
杭州大搜车(C轮)诚意求才(NodeJS服务端开发) http://t.cn/R2NXqK7
@cheergoh 如果我没有理解错你的意思的话,那就是你理解错异步了。
query.exec(function(err, list){
sleep(10000);
cb(err,list);
})
上面的代码是在主线程里同步执行的,如果你在javascript代码里有耗时操作,那就是实实在在的耗时,javascript内的任何代码都是同步执行的,绝对不会异步执行。javascript代码只能发起异步命令,这个异步命令发布完成后,程序不是傻等, 而是去处理已完成的异步请求。所以按照这个解释,你最后一个回复当然会消耗100秒。发起异步命令和异步完成后的回调时间我们假设很短,忽略不计,你发出了10条异步请求,等待回复,最快的情况我们假设是立即返回,异步处理时间也忽略不计,你发出的异步请求随即的返回了,由于是并行的,完成的先后顺序不确定,顺序其实不是关键,接下来我们来处理数据,在主线程内,我们先处理第一个10秒,完成后发送数据,第二个开始处理就是从第一个完成开始的,以此类推,最后一个耗时就是100秒。
千万不要以为回调里面代码是异步执行的,回调是同步执行的,回调执行的时候,异步请求已经结束了。javascript代码永远是同步的,里面耗时的计算是实打实的。
@coordcn 大哥,每次都看到你这么详细耐心而且深入的回答别人的问题,请收下我的膝盖 XD
@cheergoh 15楼的大哥已经解释的很清楚了
@coordcn 多谢大神耐心指点,我自己想根本不能理解。感动哭 T_T