Javascript中關於async以及awai的用法具體介紹
本篇文章主要介紹了Javascript中的async/awai的用法,將分享async / await是如何運作的,有興趣的可以了解一下
async / await是ES7的重要特性之一,也是目前社區裡公認的優秀非同步解決方案。目前,async / await這個特性已經是stage 3的建議,可以看看TC39的進度,這篇文章將分享async / await是如何運作的,閱讀本文前,希望你具備Promise、generator、yield等ES6的相關知識。
在詳細介紹async / await之前,先回顧下目前在ES6中比較好的非同步處理辦法。以下的範例中資料請求以Node.js中的request模組,資料介面採用Github v3 api文件提供的repo程式碼倉庫詳情API作為範例示範。
Promise對非同步的處理
雖然Node.js的非同步IO帶來了對高並發的良好支持,同時也讓「回呼」成為災難,很容易造成回調地獄。傳統的方式例如使用具名函數,雖然可以減少巢狀的層數,讓程式碼看起來比較清晰。但是會造成比較差的編碼和調試體驗,你需要經常使用用ctrl + f去尋找某個具名函數的定義,這使得IDE視窗經常上下來回跳動。使用Promise之後,可以很好的減少嵌套的層數。另外Promise的實作採用了狀態機,在函數裡面可以很好的透過resolve和reject進行流程控制,你可以依照順序鍊式的去執行一系列程式碼邏輯了。以下是使用Promise的一個例子:
const request = require('request'); // 请求的url和header const options = { url: 'https://api.github.com/repos/cpselvis/zhihu-crawler', headers: { 'User-Agent': 'request' } }; // 获取仓库信息 const getRepoData = () => { return new Promise((resolve, reject) => { request(options, (err, res, body) => { if (err) { reject(err); } resolve(body); }); }); }; getRepoData() .then((result) => console.log(result);) .catch((reason) => console.error(reason);); // 此处如果是多个Promise顺序执行的话,如下: // 每个then里面去执行下一个promise // getRepoData() // .then((value2) => {return promise2}) // .then((value3) => {return promise3}) // .then((x) => console.log(x))
不過Promise仍然有缺陷,它只是減少了嵌套,並不能完全消除嵌套。舉個例子,對於多個promise串列執行的情況,第一個promise的邏輯執行完之後,我們需要在它的then函數裡面去執行第二個promise,這個時候會產生一層巢狀。另外,採用Promise的程式碼看起來依然是異步的,如果寫的程式碼如果能夠變成同步該有多好!
Generator對非同步的處理
談到generator,你應該不會對它感到陌生。在Node.js中對於回呼的處理,我們常用的TJ / Co就是使用generator結合promise來實現的,co是coroutine的簡稱,藉鑑於python、#lua等語言中的協程。它可以將非同步的程式碼邏輯寫成同步的方式,這使得程式碼的閱讀和組織變得更加清晰,也便於偵錯。
const co = require('co'); const request = require('request'); const options = { url: 'https://api.github.com/repos/cpselvis/zhihu-crawler', headers: { 'User-Agent': 'request' } }; // yield后面是一个生成器 generator const getRepoData = function* () { return new Promise((resolve, reject) => { request(options, (err, res, body) => { if (err) { reject(err); } resolve(body); }); }); }; co(function* () { const result = yield getRepoData; // ... 如果有多个异步流程,可以放在这里,比如 // const r1 = yield getR1; // const r2 = yield getR2; // const r3 = yield getR3; // 每个yield相当于暂停,执行yield之后会等待它后面的generator返回值之后再执行后面其它的yield逻辑。 return result; }).then(function (value) { console.log(value); }, function (err) { console.error(err.stack); });
async / await對非同步的處理
雖然co是社群裡面的優秀非同步解決方案,但並不是語言標準,只是一個過渡方案。 ES7語言層面提供async / await去解決語言層面的難題。目前async / await 在 IE edge已經可以直接使用了,但chrome和Node.js還沒有支援。幸運的是,babel已經支援async的transform了,所以我們使用的時候引入babel就行。在開始之前我們需要介紹以下的package,preset-stage-3裡就有我們需要的async/await的編譯檔。
無論是在Browser或Node.js端都需要安裝下面的套件。
$ npm install babel-core --save $ npm install babel-preset-es2015 --save $ npm install babel-preset-stage-3 --save
這裡推薦使用babel官方提供的require hook方法。就是透過require進來後,接下來的檔案進行require的時候都會經過Babel的處理。因為我們知道CommonJs是同步的模組依賴,所以也是可行的方法。這個時候,需要寫兩個文件,一個是啟動的js文件,另一個是真正執行程式的js文件。
啟動檔index.js
require('babel-core/register'); require('./async.js');
真正執行程式的async.js
const request = require('request'); const options = { url: 'https://api.github.com/repos/cpselvis/zhihu-crawler', headers: { 'User-Agent': 'request' } }; const getRepoData = () => { return new Promise((resolve, reject) => { request(options, (err, res, body) => { if (err) { reject(err); } resolve(body); }); }); }; async function asyncFun() { try { const value = await getRepoData(); // ... 和上面的yield类似,如果有多个异步流程,可以放在这里,比如 // const r1 = await getR1(); // const r2 = await getR2(); // const r3 = await getR3(); // 每个await相当于暂停,执行await之后会等待它后面的函数(不是generator)返回值之后再执行后面其它的await逻辑。 return value; } catch (err) { console.log(err); } } asyncFun().then(x => console.log(`x: ${x}`)).catch(err => console.error(err));
注意點:
async用來申明裡麵包裹的內容可以進行同步的方式執行,await則是進行執行順序控制,每次執行一個await,程式都會暫停等待await回傳值,然後再執行之後的await。
await後面呼叫的函數需要回傳一個promise,另外這個函數是一個普通的函數即可,而不是generator。
await只能用在async函數之中,用在普通函數中會報錯。
await指令後面的 Promise 物件,運行結果可能是 rejected,所以最好把 await 指令放在 try...catch 程式碼區塊中。
其實,async / await的用法和co差不多,await和yield都是表示暫停,外麵包裹一層async 或者co來表示裡面的程式碼可以採用同步的方式進行處理。不過async / await裡面的await後面跟著的函數不需要額外處理,co是需要將它寫成一個generator的。
【相關推薦】
#2. JavaScript運動框架之多值運動的具體介紹(四)
3. JavaScript運動框架之多物體任意值運動的範例程式碼分享(三)
4. JavaScript運動框架如何解決防抖動問題、懸浮對聯(二)
5. JavaScript運動框架之如何解決速度正負取整問題(一)
以上是Javascript中關於async以及awai的用法具體介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

如何使用WebSocket和JavaScript實現線上語音辨識系統引言:隨著科技的不斷發展,語音辨識技術已成為了人工智慧領域的重要組成部分。而基於WebSocket和JavaScript實現的線上語音辨識系統,具備了低延遲、即時性和跨平台的特點,成為了廣泛應用的解決方案。本文將介紹如何使用WebSocket和JavaScript來實現線上語音辨識系

WebSocket與JavaScript:實現即時監控系統的關鍵技術引言:隨著互聯網技術的快速發展,即時監控系統在各個領域中得到了廣泛的應用。而實現即時監控的關鍵技術之一就是WebSocket與JavaScript的結合使用。本文將介紹WebSocket與JavaScript在即時監控系統中的應用,並給出程式碼範例,詳細解釋其實作原理。一、WebSocket技

如何利用JavaScript和WebSocket實現即時線上點餐系統介紹:隨著網路的普及和技術的進步,越來越多的餐廳開始提供線上點餐服務。為了實現即時線上點餐系統,我們可以利用JavaScript和WebSocket技術。 WebSocket是一種基於TCP協定的全雙工通訊協議,可實現客戶端與伺服器的即時雙向通訊。在即時線上點餐系統中,當使用者選擇菜餚並下訂單

如何使用WebSocket和JavaScript實現線上預約系統在當今數位化的時代,越來越多的業務和服務都需要提供線上預約功能。而實現一個高效、即時的線上預約系統是至關重要的。本文將介紹如何使用WebSocket和JavaScript來實作一個線上預約系統,並提供具體的程式碼範例。一、什麼是WebSocketWebSocket是一種在單一TCP連線上進行全雙工

JavaScript和WebSocket:打造高效的即時天氣預報系統引言:如今,天氣預報的準確性對於日常生活以及決策制定具有重要意義。隨著技術的發展,我們可以透過即時獲取天氣數據來提供更準確可靠的天氣預報。在本文中,我們將學習如何使用JavaScript和WebSocket技術,來建立一個高效的即時天氣預報系統。本文將透過具體的程式碼範例來展示實現的過程。 We

JavaScript教學:如何取得HTTP狀態碼,需要具體程式碼範例前言:在Web開發中,經常會涉及到與伺服器進行資料互動的場景。在與伺服器進行通訊時,我們經常需要取得傳回的HTTP狀態碼來判斷操作是否成功,並根據不同的狀態碼來進行對應的處理。本篇文章將教你如何使用JavaScript來取得HTTP狀態碼,並提供一些實用的程式碼範例。使用XMLHttpRequest

用法:在JavaScript中,insertBefore()方法用於在DOM樹中插入一個新的節點。這個方法需要兩個參數:要插入的新節點和參考節點(即新節點將要插入的位置的節點)。

JavaScript是一種廣泛應用於Web開發的程式語言,而WebSocket則是一種用於即時通訊的網路協定。結合二者的強大功能,我們可以打造一個高效率的即時影像處理系統。本文將介紹如何利用JavaScript和WebSocket來實作這個系統,並提供具體的程式碼範例。首先,我們需要明確指出即時影像處理系統的需求和目標。假設我們有一個攝影機設備,可以擷取即時的影像數
