javascript的灵活在于函数能够看成函数的参数来传递,以及它的异步回调思想。可是这就带了一个很严重的问题,那就是回调次数过多,会影响代码结构,多层嵌套影响代码的可阅读性,也不便于书写。javascript
举个例子,用nodejs写爬虫,若是要爬取4个页面,而且要求爬取完上一个在爬取下一个,那么代码就得这样书写:html
var http=require('http')java
var url_arr=['http://www.cnblogs.com/wl843022618/p/6767066.html',node
'http://www.cnblogs.com/wl843022618/p/6422970.html',promise
'http://www.cnblogs.com/wl843022618/p/6422755.html',异步
'http://www.cnblogs.com/wl843022618/p/6375052.html']函数
http.get(url_arr[0],function(res){ui
res.on('data',function(){url
......htm
})
res.on('end',function(){
http.get(url_arr[1],function(res){
res.on('data',function(){
......
})
res.on('end',function(){
http.get(url_arr[2],function().............
})
})
})
})
其中我省略了许多行,也许有些朋友看不懂这个代码,不要紧,我用request写一遍,以下:
var request=require('request')
var url_arr=['http://www.cnblogs.com/wl843022618/p/6767066.html',
'http://www.cnblogs.com/wl843022618/p/6422970.html',
'http://www.cnblogs.com/wl843022618/p/6422755.html',
'http://www.cnblogs.com/wl843022618/p/6375052.html']
request(url_arr[0],function(err,response,body){
request(url_arr[1],function(err,response,body){
request(url_arr[2],function(err,response,body){
request(url_arr[3],function(err,response,body){
})
})
})
})
4层嵌套,没带爬取后的处理,还算清晰,那若是是100次嵌套,请问你怕不怕,我反正是怕了,固然了我刚遇到这问题的时候一脸懵逼,后来知道了Promise感受好像解决了这个问题,可是并不完美:用Promise封装了request以后,代码会以下:
promise_request(url_arr[0])
.then(function(){})
.then(function(){})
......
依然没有简化代码,只是让代码看起来能看懂代码的处理流程,可是我有不同的解决办法,那就是递归写法:
很简单:
var request=require('request')
var i==0
request(url_arr[0],function callback(err,response,body){
if(i==url_arr.length){
return
}
i++
request(url_arr[i],callback)
})
再次简化:
var request=require('request')
request(url_arr.shift(),function callback(err,response,body){
//....爬取后的处理写在这里
if(0==url_arr.length){
return
}
request(url_arr[i],callback)
})