用Async/Await控制異步,實現完美小爬蟲

在JavaScript裏,全部的操做都是經過異步完成,不須要像python同樣按順序執行,很是容易由於某個函數執行速度過慢致使整個程序阻塞,從效率上來講遠遠低於JavaScript的原生異步機制。固然,python也能夠實現異步功能,可是會麻煩很多,尤爲對於一些代碼量少的小爬蟲很是不友好。javascript

在我上篇爬蟲文章裏就提到了很多異步帶來的好處,但同時壞處也很多,不少時候會致使輸出的結果並非咱們想要的。好比咱們但願在爬取到全部的數據後纔開始執行處理函數,但JavaScript會在爬取數據的同時執行處理函數,直接致使爬蟲出錯。java

0.舉個例子:

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

1.如何建立Async使用

首先要建立一個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)
    })
}
複製代碼

來運行一下改造後的代碼: 函數

2.如何處理錯誤

還記得有一個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

相關文章
相關標籤/搜索