摘要:標準已于年月份正式定稿了,并廣泛支持最新的特性異步函數(shù)。為了領(lǐng)會,我們需要回到普通回調(diào)函數(shù)中進一步學(xué)習(xí)。從此編寫回調(diào)函數(shù)不再那么痛苦?;卣{(diào)是一個函數(shù),可以將結(jié)果傳遞給函數(shù)并在該函數(shù)內(nèi)進行調(diào)用,以便作為事件的響應(yīng)。
ES2017標準已于2017年6月份正式定稿了,并廣泛支持最新的特性:異步函數(shù)。如果你曾經(jīng)被異步 JavaScript 的邏輯困擾,這么新函數(shù)正是為你設(shè)計的。
異步函數(shù)或多或少會讓你編寫一些順序的 JavaScript 代碼,但是卻不需要在 callbacks、generators 或 promise 中包含你的邏輯。
如下代碼:
function logger() {
let data = fetch("http://sampleapi.com/posts") console.log(data)
}
logger()
這段代碼并未實現(xiàn)你的預(yù)期。如果你是在JS中編寫的,那么你可能會知道為什么。
下面這段代碼,卻實現(xiàn)了你的預(yù)期。
async function logger() {
let data = await fetch("http:sampleapi.com/posts") console.log(data)
}
logger()
這段代碼起作用了,從直觀上看,僅僅只是多了 async 和 await 兩個詞。
在深入學(xué)習(xí) async 和 await 之前,我們需要先理解 Promise。為了領(lǐng)會 Promise,我們需要回到普通回調(diào)函數(shù)中進一步學(xué)習(xí)。
Promise 是在 ES6 中引入的,并促使在編寫 JavaScript 的異步代碼方面,實現(xiàn)了巨大的提升。從此編寫回調(diào)函數(shù)不再那么痛苦。
回調(diào)是一個函數(shù),可以將結(jié)果傳遞給函數(shù)并在該函數(shù)內(nèi)進行調(diào)用,以便作為事件的響應(yīng)。同時,這也是JS的基礎(chǔ)。
function readFile("file.txt", (data) => {
// This is inside the callback function console.log(data)
}
這個函數(shù)只是簡單的向文件中記錄數(shù)據(jù),在文件完成之前進行讀取是不可能的。這個過程似乎很簡單,但是如果想要按順序讀取并記錄五個不同的文件,需要怎么實現(xiàn)呢?
沒有 Promise 的時候,為了按順序執(zhí)行任務(wù),就需要通過嵌套回調(diào)來實現(xiàn),就像下面的代碼:
// This is officially callback hell
function combineFiles(file1, file2, file3, printFileCallBack) {
let newFileText = "" readFile(string1, (text) => { newFileText += text readFile(string2, (text) => { newFileText += text readFile(string3, (text) => { newFileText += text printFileCallBack(newFileText) } } }
}
這就很難推斷函數(shù)下面會發(fā)生什么,同時也很難處理各種場景下發(fā)生的錯誤,比如其中某個文件不存在的情況。
這正是 Promise 的優(yōu)勢所在,Promise 是對還未產(chǎn)生的數(shù)據(jù)的一種推理。Kyle Simpson 將 Promise 解釋為:就像在快餐店里點餐一樣。
點餐
為所點的午餐付費,并拿到排隊單號
等待午餐
當你的午餐準備好了,會叫你的單號提醒你取餐
收到午餐
正如上面的這種場景,當你等餐時,你是無法吃到午餐的,但是你可以提前為吃午餐做好準備。你可以進行其它事情,此時你知道午餐就要來了,雖然此刻你還無法享用它,但是這個午餐已經(jīng)“promise”給你了。這就是所謂的 promise,表示一個最終會存在的數(shù)據(jù)的對象。
readFile(file1)
.then((file1-data) => { /* do something */ }) .then((previous-promise-data) => { /* do the next thing */ }) .catch( /* handle errors */ )
上面是 Promise?語法。它主要的優(yōu)點就是可以將隊列事件以一種直觀的方式鏈接在一起。雖然這個示例清晰易懂,但是還是用到了回調(diào)。Promise 只是讓回調(diào)顯得比較簡單和更加直觀。
最佳方式:async / await若干年前,async 函數(shù)納入了 JavaScript 生態(tài)系統(tǒng)。就在上個月,async 函數(shù)成為了 JavaScript 語言的官方特性,并得到了廣泛支持。
async 和 await 是建立在 Promise 和 generator上。本質(zhì)上,允許我們使用 await 這個關(guān)鍵詞在任何函數(shù)中的任何我們想要的地方進行暫停。
async function logger() {
// pause until fetch returns let data = await fetch("http://sampleapi.com/posts") console.log(data)
}
上面這段代碼運行之后,得到了想要的結(jié)果。代碼從 API 調(diào)用中記錄了數(shù)據(jù)。
這種方式的好處就是非常直觀。編寫代碼的方式就是大腦思考的方式,告訴腳本在需要的地方暫停。
另一個好處是,當我們不能使用 promise 時,還可以使用 try 和 catch:
async function logger () {
try { let user_id = await fetch("/api/users/username") let posts = await fetch("/api/`${user_id}`") let object = JSON.parse(user.posts.toString()) console.log(posts) } catch (error) { console.error("Error:", error) }
}
上面是一個刻意寫錯的示例,為了證明了一點:在運行過程中,catch 可以捕獲任何步驟中發(fā)生的錯誤。至少有三個地方,try 可能會失敗,這是在異步代碼中的一種最干凈的方式來處理錯誤。
我們還可以使用帶有循環(huán)和條件的 async 函數(shù):
async function count() {
let counter = 1 for (let i = 0; i < 100; i++) { counter += 1 console.log(counter) await sleep(1000) }
}
這是一個很簡答的例子,如果運行這段程序,將會看到代碼在 sleep 調(diào)用時暫停,下一個循環(huán)迭代將會在1秒后啟動。
相信我們已經(jīng)感受到了 asyns 和 await 的美妙之處,接下來讓我們深入了解一下細節(jié):
async 和 await 建立在 Promise 之上。使用 async,總是會返回一個 Promise。請記住這一點,因為這也是容易犯錯的地方。
當執(zhí)行到 await 時,程序會暫停當前函數(shù),而不是所有代碼
async 和 await 是非阻塞的
依舊可以使用 Promise helpers,例如 Promise.all( )
正如之前的示例:
async function logPosts () {
try {
let user_id = await fetch("/api/users/username")
let post_ids = await fetch("/api/posts/${user_id}")
let promises = post_ids.map(post_id => {
return fetch("/api/posts/${post_id}")
}
let posts = await Promise.all(promises)
console.log(posts)
} catch (error) {
console.error("Error:", error)
}
}
await 只能用于聲明為 async 的函數(shù)中
因此,不能在全局范圍內(nèi)使用 await
如下代碼:
// throws an error
function logger (callBack) {
console.log(await callBack)
}
// works!
async function logger () {
console.log(await callBack)
}
現(xiàn)已正式可用到2017年6月,幾乎所有瀏覽器都可以使用 async 和 await。為了確保你的代碼隨時可用,則需要使用 Babel 將你的 JavaScript 代碼編譯為舊瀏覽器也支持的語法。
如果對更多ES2017內(nèi)容感興趣,請訪問ES2017特性的完整列表。
JavaScript 開發(fā)工具推薦SpreadJS 純前端表格控件是基于 HTML5 的 Java 電子表格和網(wǎng)格功能控件,提供了完備的公式引擎、排序、過濾、輸入控件、數(shù)據(jù)可視化、Excel 導(dǎo)入/導(dǎo)出等功能,適用于 .NET、Java 和移動端等各平臺在線編輯類 Excel 功能的表格程序開發(fā)。
原文鏈接:https://css-tricks.com/using-...
轉(zhuǎn)載請注明出自:葡萄城控件
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/87415.html
摘要:定期召開會議,會議由會員公司的代表與特邀專家出席。新版本將會包含每年截止時間之前完成的所有特性。它引入了一個新的構(gòu)造函數(shù)和具有輔助函數(shù)的命名空間對象。 導(dǎo)言:ECMAScript的演化不會停止,但是我們完全沒必要害怕。除了ES6這個史無前例的版本帶來了海量的信息和知識點以外,之后每年一發(fā)的版本都僅僅帶有少量的增量更新,一年更新的東西花半個小時就能搞懂了,完全沒必要畏懼。本文將帶您花大約...
摘要:特性概述整理自,歸納于筆者的現(xiàn)代開發(fā)語法基礎(chǔ)與實踐技巧系列文章中也歡迎關(guān)注前端每周清單系列獲得一手資訊。本部分則介紹了新的構(gòu)造器與包含靜態(tài)方法的命名空間對象。 ECMAScript 2017(ES8)特性概述 整理自 ES8 was Released and here are its Main New Features,歸納于筆者的現(xiàn)代 JavaScript 開發(fā):語法基礎(chǔ)與實踐技巧系...
摘要:是中國研發(fā)中心發(fā)起的開源企業(yè)級容器項目,如今已正式加入的社區(qū)中的社區(qū)是由官方設(shè)定但由社區(qū)的合作伙伴和用戶的貢獻而來的。下圖是的社區(qū)的截圖請注意,目前的條目僅適用于環(huán)境。最后必須提出的一點是,的社區(qū)是由社區(qū)支持的。 Harbor是VMware中國研發(fā)中心發(fā)起的開源企業(yè)級容器Registry項目,如今Harbor已正式加入Rancher的社區(qū)Catalog中!Rancher的社區(qū)Catal...
摘要:,微軟發(fā)布,同時發(fā)布了,該語言模仿同年發(fā)布的。,公司在瀏覽器對抗中沒落,將提交給國際標準化組織,希望能夠成為國際標準,以此抵抗微軟。同時將標準的設(shè)想定名為和兩類。,尤雨溪發(fā)布項目。,正式發(fā)布,并且更名為。,發(fā)布,模塊系統(tǒng)得到廣泛的使用。 前言 作為程序員,技術(shù)的落實與鞏固是必要的,因此想到寫個系列,名為 why what or how 每篇文章試圖解釋清楚一個問題。 這次的 why w...
閱讀 2435·2021-11-23 10:04
閱讀 1508·2021-09-02 15:21
閱讀 900·2019-08-30 15:44
閱讀 1071·2019-08-30 10:48
閱讀 717·2019-08-29 17:21
閱讀 3564·2019-08-29 13:13
閱讀 1991·2019-08-23 17:17
閱讀 1795·2019-08-23 17:04