非同步程式設計新方式async await

2022-03-03 21:36:46 字數 3707 閱讀 6835

實際上對async/await並不是很陌生,早在阮大大的es6教程裡面就接觸到了,但是一直處於理解並不熟練使用的狀態,於是決定重新學習並且總結一下,寫了這篇博文。如果文中有錯誤的地方還請各位批評指正!

1.async/await 是非同步**的新方式

2.async/await 基於 promise 實現

3.async/await使得非同步**更像同步**

4.await 只能用在 async 函式中,不能用在普通函式中 await 關鍵字後面必須跟 promise 物件 函式執行到 await 後,promise 函式執行完畢,但因為 promise 內部一般都是非同步函式,所以事件迴圈會一直 等待,直到事件輪詢檢查到 promise 有了狀態 resolve 或 reject 才重新執行這個函式後面的內容

async函式es2017標準引入的語法,是generator函式的語法糖,因此其相對於generator函式,具有以下基本特點。

內建執行器:使用async函式可以像使用普通函式一樣,直接呼叫即可執行。不用像generator函式一樣使用co模組來實現流程控制。

語義化更強:async關鍵字表示是乙個非同步的函式,await表示需要等待執行。相對於yield表示式,語義化更強。

返回值是promise:async函式返回值是promise物件,這比generator函式的返回值是iterator物件方便多了,可以使用then方法來指定下一步的操作。

async函式返回乙個 promise 物件,async函式內部return語句返回的值,會成為then方法**函式的引數。當函式執行的時候,一旦遇到await就會先返回,等到非同步操作完成,再接著執行函式體內後面的語句。

async function f() 

f().then(v => console.log(v))

// "hello world"

上面**中,函式f內部return命令返回的值,會被then方法**函式接收到。

async函式內部丟擲錯誤,會導致返回的 promise 物件變為reject狀態。丟擲的錯誤物件會被catch方法**函式接收到。

async function f() 

f().then(

v => console.log('resolve', v),

e => console.log('reject', e)

)//reject error: 出錯了

async函式返回的 promise 物件,必須等到內部所有await命令後面的 promise 物件執行完,才會發生狀態改變,除非遇到return語句或者丟擲錯誤。也就是說,只有async函式內部的非同步操作執行完,才會執行then方法指定的**函式。

async function gettitle(url) 

gettitle('').then(console.log)

// "ecmascript 2017 language specification"

上面**中,函式gettitle內部有三個操作:抓取網頁、取出文字、匹配頁面標題。只有這三個操作全部完成,才會執行then方法裡面的console.log。

如果await命令後面是乙個 promise 物件,返回該物件的結果。如果不是 promise 物件,就直接返回對應的值。

async function f() 

f().then(v => console.log(v))

// 123

如果await命令後面是乙個thenable物件(即定義了then方法的物件),那麼await會將其等同於 promise 物件。

class sleep 

then(resolve, reject)

}(async () => )();

// 1000

如果await命令後面的 promise 物件變為reject狀態,則reject的引數會被catch方法的**函式接收到。

async function f() 

f().then(v => console.log(v))

.catch(e => console.log(e))

// 出錯了

任何乙個await語句後面的 promise 物件變為reject狀態,那麼整個async函式都會中斷執行。

async function f()

為了避免一些不必要的麻煩,建議把await放入try—catch中

async function myfunction()  catch (err) 

}// 另一種寫法

async function myfunction() );

}

(1)async函式內部的非同步操作執行完,根據其執行的狀態,對應執行then或catch

(2)遇到await就會先返回,等到非同步操作完成,再接著執行函式體內後面的語句。

(3)任何乙個await語句後面的 promise 物件變為reject狀態,那麼整個async函式都會中斷執行。

async 函式的實現原理,就是將 generator 函式和自動執行器,包裝在乙個函式裡。【generator可以理解為乙個狀態機,內部封裝了很多狀態,同時返回乙個迭代器iterator物件。可以通過這個迭代器遍歷相關的值及狀態。 generator的顯著特點是可以多次返回,每次的返回值作為迭代器的一部分儲存下來,可以被我們顯式呼叫。】

async function fn(args) 

// 等同於

function fn(args) );

}

所有的async函式都可以寫成上面的第二種形式,其中的spawn函式就是自動執行器。下面給出spawn函式的實現

function spawn(genf)  catch(e) 

if(next.done)

promise.resolve(next.value).then(function(v) );

}, function(e) );

});}

step(function() );

});}

1.await只能使用在async函式內部,在普通函式中使用會報錯

2.任何乙個await語句後面的 promise 物件變為reject狀態,那麼整個async函式都會中斷執行。最好將其放入try—catch中

3.在某些場景下並不適合使用await,會增加頁面互動時間,要合理利用

「通電」新方式

如果無法斬斷給我們生活 通電 的各種電源線 至少現在可以讓它們看 上去更加賞心悅目一些。我曾經探討過各種試圖將亂麻一般的電線規整得井井有條的方法 參見2005年8月8日的 逃出線路叢林 然而任何解決方案都非完美無暇 我得第乙個跳出來承認我在這方面做得很糟糕。不過現在有了一種新方法 一種名為eubiq...

Winsock非同步方式程式設計例項 原創

這是乙個winsock非同步程式設計的例子 這個服務監聽1000埠,可以使用 tel localhost 1000進行測試,最大允許20個連線 include include pragma ment lib,ws2 32.lib define max sockets 20 define max ba...

改進 ThinkJS 的非同步程式設計方式

thinkjs 是奇舞團開源的一款 node mvc 框架,主要由 welefen 開發。簡單介紹一下 thinkjs 是乙個快速 簡單的基於 mvc 和物件導向的輕量級 node.js 開發框架,遵循 mit 協議發布。秉承簡潔易用的設計原則,在保持出色的效能和至簡的 同時,注重開發體驗和易用性,...