async await的多非同步處理方式

2021-10-08 11:05:20 字數 2165 閱讀 8110

寫爬蟲時候遇到的批量非同步處理的一些思考和總結。

async/await是es2017加入的標準,它允許用同步的寫法來進行非同步的操作,它的本質是es6引入的promisegenerator函式的語法糖。

async

function

sleepy()

/** * @params sleeptime

* @params awaketext

* @params error

* @returns promise*/

function

sleep

(sleeptime, awaketext, error)

else

}, sleeptime);}

);}

通過async字首定義乙個特殊函式,在函式的內部可以使用await關鍵字來接乙個promise型別的值,按照從上到下的順序來執行函式。先通過settimeoutpromise定義乙個最簡單的非同步函式sleep

執行sleepy函式之後,會按照順序輸出i awake -> and sleep -> awake now

前文也說到了async/await實質上是promisegenerator的語法糖,上文的sleepy可以改寫成如下形式:

function

*sleepy()

實際過程中,批量處理非同步請求時常常會遇到與期望不符的情況。我們假設存在複數的請求,我們需要得到這些請求的值。

// sleepy 非同步的請求

const requests =

newarray(10

).fill

(sleepy)

;const results = requests.

map(

async

(request)

=>

await

request()

);// [promise]

上面的例子嘗試將陣列中複數的請求通過map方法返回所有請求的結果來進行批量處理,實際上得到的只能是乙個pending狀態的promise陣列。其實我們很容易想到這樣產生的原因,map等一系列陣列方法是在es5版本加入的,當時沒有promise的提案,更沒有async/await。當時的map方法應該是直接執行傳入的函式。

// map 的簡單實現

array.prototype.

map=

function

(handler)

return handler;

}

但是既然既然返回的是promise型別,其實可以很簡單的使用promise.all的 api 來完成想要操作的結果。

promise.

all(

requests.

map(request =>

request()

)).then

(results =>

);

這樣能夠實現併發多個請求,並在所有請求處理完畢後返回處理結果陣列的需求。而在我自己的爬蟲專案中,需要開啟很多個詳情頁並爬取對應的資料。如果同時併發請求,在資料量大的情況話,可能順時切開上百個詳情頁。此時需要順序完成請求操作。

(

async

function()

})()

;

因為await關鍵字只能在async函式定義中有效。因此使用iife來產生async函式環境,達成次序執行的目的。

非同步async await寫法

async await 用asyncio提供的 asyncio.coroutine可以把乙個generator標記為coroutine型別,然後在coroutine內部用yield from呼叫另乙個coroutine實現非同步操作。為了簡化並更好地標識非同步io,從python 3.5開始引入了新...

非同步操作async await

async函式的特點 例 router.get testasync async ctx 1000 const b await 123const c await new promise resolve,reject 2000 ctx.body 看看 的執行過程,它裡面遇到了await,await 表示...

利用 async await 的非同步程式設計

通過使用非同步程式設計,你可以避免效能瓶頸並增強你的應用程式的總體響應能力。從 vs 2012 開始,新引入了乙個簡化的方法,稱為非同步程式設計。我們在 net 4.5 中和 windows 執行時中使用非同步,編譯器它會幫助了我們降低了曾經進行的高難度非同步 編寫的工作,但邏輯結構卻類似於同步 因...