在JavaScript裏,全部的操做都是經過異步完成,不須要像python同樣按順序執行,很是容易由於某個函數執行速度過慢致使整個程序阻塞,從效率上來講遠遠低於JavaScript的原生異步機制。固然,python也能夠實現異步功能,可是會麻煩很多,尤爲對於一些代碼量少的小爬蟲很是不友好。javascript
在我上篇爬蟲文章裏就提到了很多異步帶來的好處,但同時壞處也很多,不少時候會致使輸出的結果並非咱們想要的。好比咱們但願在爬取到全部的數據後纔開始執行處理函數,但JavaScript會在爬取數據的同時執行處理函數,直接致使爬蟲出錯。java
const getWeb = function(){
requestSomething()
setData()
return console.log(「3.程序結束」)
}
const requestSomething = function(){
setTimeout(() => console.log(‘1.網頁數據爬取完畢!’),2000)
}
const setData = function(){
console.log(‘2.開始處理數據!’)
}
getWeb()
複製代碼
輸出結果: python
看到結果咱們發現,明明是爬取網頁的requestSomething函數先執行,可是先輸出結果的倒是處理函數setData,甚至在整個getWeb函數返回後纔開始輸出爬取結果。git
爲了解決這個問題,束縛住JavaScript這匹脫繮的野馬,這裏就須要用到Async函數,讓JavaScript程序能按照咱們但願的順序執行。github
首先要建立一個async函數,在咱們但願控制異步的地方使用await來進行控制,好比:異步
const getWeb = async function(){
await requestSomething()
setData()
return console.log(「3.程序結束」)
}
複製代碼
接下來還須要改造requestSomething函數,首先直接返回一個Promise對象,裏面經過匿名函數接收兩個參數,分別是resolve和reject,當執行resoleve()時表示當前函數執行完畢,而reject()則是返回錯誤信息,咱們先來看resoleve:async
const requestSomething = function(){
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log(‘1.網頁數據爬取完畢!’)
resolve()
},2000)
})
}
複製代碼
來運行一下改造後的代碼: 函數
還記得有一個reject命令嗎?在爬取失敗時,能夠經過reject返回失敗內容,而後使用catch方法來輸出,如今,來改造一下代碼,在爬取失敗時輸出失敗信息:ui
const requestSomething = function(){
return new Promise((resolve, reject) => {
let err = ‘1.爬取失敗!’
if(typeof err != ‘undefined’){
//返回錯誤信息
reject(err)
} else (
setTimeout(() => {
console.log(‘1.網頁數據爬取完畢!’)
resolve()
},2000)
)
})
}
const getWeb = async function(){
//經過catch捕捉返回的錯誤信息
await requestSomething().catch(e => console.log(e))
setData()
return console.log(「3.程序結束」)
}
複製代碼
輸出結果: spa
至此,咱們已經成功控制住了異步程序,能夠在小爬蟲裏直接應用了!
完整代碼: github.com/Card007/Nod…
也歡迎訪問個人主頁: Nothlu’s Blog