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)
})