這個系列到這里應該就是最后一節(jié)了,前兩章著重講了promise,為什么著重講promise呢?因為在用法上promise要比async await難一些,而且promise本身又不是一個語法糖。沒有掌握的時候用起來就會有很多顧慮,async await卻沒有這種顧慮,用法簡單、語義清晰。
網(wǎng)站建設公司,為您提供網(wǎng)站建設,網(wǎng)站制作,網(wǎng)頁設計及定制網(wǎng)站建設服務,專注于成都定制網(wǎng)頁設計,高端網(wǎng)頁制作,對成都iso認證等多個行業(yè)擁有豐富的網(wǎng)站建設經(jīng)驗的網(wǎng)站建設公司。專業(yè)網(wǎng)站設計,網(wǎng)站優(yōu)化推廣哪家好,專業(yè)成都網(wǎng)站推廣優(yōu)化,H5建站,響應式網(wǎng)站。
基礎預熱:你好,JavaScript異步編程---- 理解JavaScript異步的美妙
理解異步之美:Promise與async await(一)
理解異步之美:Promise 與 async await(二)
下面就要開始學習async await了
對于java語言來說,迭代器是一個很基本的模式,list與set結(jié)構(gòu)都內(nèi)置了迭代器。
但是javascript并沒有這種結(jié)果(ps:ES6提供了set,而且也可以實現(xiàn)迭代器),但是我們對這種模式實用的并不是特別多。
迭代器模式是指提供一種方法順序訪問一個聚合對象中的各個元素,而又不需要暴露該對象的內(nèi)部表示。
so:迭代器就是在不暴露對象的內(nèi)部表示的情況下,能夠遍歷整個元素
核心嘛就是:不暴露內(nèi)部,可以遍歷內(nèi)部
下面我們就來實現(xiàn)一個簡單的迭代器
// 在數(shù)據(jù)獲取的時候沒有選擇深拷貝內(nèi)容,
// 對于引用類型進行處理會有問題
// 這里只是演示簡化了一點
function Iterdtor(arr){
let data = [];
if(!Array.isArray(arr)){
data = [arr];
}else{
data = arr;
}
let length = data.length;
let index = 0;
// 迭代器的核心next
// 當調(diào)用next的時候會開始輸出內(nèi)部對象的下一項
this.next = function(){
let result = {};
result.value = data[index];
result.done = index === length-1? true : false;
if(index !== length){
index++;
return result;
}
// 當內(nèi)容已經(jīng)沒有了的時候返回一個字符串提示
return 'data is all done'
};
}
let arr = [1,2,3,4,5,6];
// 生成一個迭代器對象。
let iterdtor = new Iterdtor(arr);
iterdtor.next()
iterdtor.next()
cdn.xitu.io/2018/8/21/1655c7763e4561ce?w=414&h=310&f=png&s=41212">
這就符合迭代器模式的特點,并沒有暴露內(nèi)部的對象,
通過next的方法可以遍歷內(nèi)部對象。
說到現(xiàn)在很多人應該還沒理解為什么要說迭代器。
這兩個理由是不是一下子就說明寫迭代器是很有用處的。
書寫一個簡單的Generator函數(shù)
function *Iterdtor(){
console.log(1);
yield '123';
console.log(2);
yield '234';
console.log(3);
return '345'
}
let iterator = Iterdtor();
我們執(zhí)行了一下Generator函數(shù)返回一個迭代器。通過next方法,可以阻塞性的去執(zhí)行Generator的代碼。
一說到阻塞大家就想到同步等待阻塞線程導致頁面十分卡頓,明明不是一件很好的事情,為什么要用這種東西呢?
下面我們就聊聊這種阻塞性的方式有什么好處呢?
在Generator函數(shù)中,迭代器調(diào)用next函數(shù)后,會一直執(zhí)行到有yield標示的位置停止。等待next的下一次調(diào)用后,代碼會繼續(xù)執(zhí)行到下個yield表示。沒有yield的話就一執(zhí)行到最后return的位置(沒有return就會一直執(zhí)行完所有的代碼,這句話好像是個廢話)。
代碼就像擠牙膏一樣,擠一點出一點擠一點出一點,最后沒有卡頓的地方,一口氣擠到底。
所以說如果實用Generator的方式來處理異步的請求會是怎樣的一種感覺。
// 偽代碼
let ajaxSign = false;
function *ajaxGetSomething(){
ajaxSomethingOne().then(res=>{ajaxSign = true})
yield
ajaxSign = false;
ajaxSomethingSecond().then(res=>{ajaxSign = true})
}
let iterator = ajaxGetSomething();
iterator.next();
while(ajaxSign){
iterator.next()
}
如果以這種方式來實現(xiàn)異步的請求會怎樣,
1:有一個標志代表ajax請求完成。
2:當標志為true時代表ajax執(zhí)行完成,可以進行下一個事件了。
3:當標志為false代碼ajax還未執(zhí)行完成,繼續(xù)阻塞下面的代碼。
4:當?shù)谝粋€標志為true時,執(zhí)行next(),然后發(fā)現(xiàn)到下一個yield之間有異步的代碼,將標志設置為false,開始執(zhí)行ajax的事情,阻塞著后面的內(nèi)容。
5:當ajax完成后把標志設置為true,開始2的內(nèi)容做的事情不斷執(zhí)行著直到整個迭代器完成。
這種方式讓我們體會到另一種處理異步的方式,就是阻塞時的去執(zhí)行多個串行的異步任務,這樣可以感受同步的寫法去書寫異步的代碼,也就不會在不合適的時間去拿去異步的產(chǎn)生的數(shù)據(jù),你阻塞著線程,你不等他執(zhí)行完,你取值的操作也做不了呀。
說到這里如何使用他們就比較清晰明了了吧
async function ajaxGetData(){
xxxx
dosomething()
await ajaxGetDataFirst()
dosomething()
await ajaxGetDataSecond()
dosomething()
xxx
}
ajaxGetData()
這個時候我們使用async函數(shù)來處理異步效果就很清晰了,
我們做了一些事情,然后到一個異步的ajax請求后,等待ajaxGetDataFirst這個異步的事件執(zhí)行完畢后,開始繼續(xù)做一些事情,到了第二個ajax異步請求ajaxGetDataSecond(),開始執(zhí)行阻塞住函數(shù)的執(zhí)行,等待異步事件執(zhí)行完畢后就繼續(xù)做下面的事情。用await關鍵字的時候就是在告訴下面的代碼,這塊你得給我等著,wait我執(zhí)行完了才能輪到你 understand?總之a(chǎn)wait吊極了。
await在什么時候可以用? 只有在async函數(shù)體內(nèi)部使用,而且這個作用范圍是不可以繼承下去的。
在promise中怎么使用async函數(shù)
new Promsie(async (resolve,reject)=>{
await xxx
})
// 這樣的async才能使await有效果,書寫在promise之外的話await就會像上面一樣報錯
await 可以接收一個同步的事情嗎?繼續(xù)執(zhí)行下去不阻塞
async函數(shù)的返回值是什么?
async函數(shù)的返回值是一個promise對象,
???? what 返回了一個promise對象。這有啥用呢?請聽下面分析
這就代表著你在執(zhí)行完所有的異步請求后還可以繼續(xù)將你需要的結(jié)果用return的方式保存在一個promise對象中。promise的用處是什么?他好像可以存儲一個值在指定情況下觸發(fā)一個回調(diào)函數(shù)(這個不理解的可以看一下上一篇內(nèi)容哈)所以這可以幫助我們把內(nèi)部的異步請求的數(shù)據(jù)拋出到函數(shù)外部來。
下面的使用場景:
在使用場景中,我們有的時候需要異步的一個結(jié)果,比如ajax請求的結(jié)果,這個時候我們希望得到這個異步的結(jié)果怎么辦?
這個時候await可以幫助我,在執(zhí)行完異步的操作的時候拿到結(jié)果,在拿到結(jié)果后順序執(zhí)行下去。直到return的時候把這個結(jié)果 return出去,
async function fn(){
let result = await new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve(100)
},10000)
}).then(res=>{
return res
})
return result
}
let a = fn()
async function fn(){
let result = await new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve(100)
},10000)
})
return result
}
let a = fn()
這兩種方式都可以等待異步的promise執(zhí)行完成之后再賦值給result,這個時候,我們返回的a就是一個pending狀態(tài)的promise對象,上一章節(jié)我們講過了promise的基本原理,后面的操作我就不多提了,所以得到你想要的內(nèi)容的promsie你就會操作了。
這個時候我們async內(nèi)的異步操作的結(jié)果自然而然的可以拋出到函數(shù)外部來使用,可以解決很多的業(yè)務的封裝問題了。
async 與Generator的區(qū)別是什么?
async是Generator的語法糖,Generator是可以用來實現(xiàn)async的,用Generator來實現(xiàn)async的核心就是實現(xiàn)這種不需next調(diào)用自執(zhí)行的內(nèi)容,這是我以后要進行學習的(目前時間不是很充裕,打算學好之后出一個特別篇好好實現(xiàn)以下async)
這一節(jié)內(nèi)容并沒有講很多async的內(nèi)容,反而是先講了迭代器,再講了Generator,最后對async的使用簡單介紹了一下,這是我在學習async時的順序,async用起來容易、同步的寫法也比較熟悉,but!!!易用的東西往往代表著方法內(nèi)部蘊含很多你不知道的東西,
這才是我們要挖掘的AV8D!!!!
異步的事情我們理解了,異步程序執(zhí)行的過程,了解了event table,任務隊列,宏任務微任務的執(zhí)行先后條件。了解了異步promise的用法,promise的實現(xiàn)機制、async的用法,以及衍生出來的迭代器知識。
這一段時間和邊學習邊產(chǎn)出文章,有一種被大家鞭策的感覺,哈哈哈哈哈。鞭策這個詞有點怪怪的,這個過程中我發(fā)現(xiàn)學習不能只有興趣,興趣可以幫你研究你喜歡的內(nèi)容時有無限的動力,上了發(fā)條一樣,在你低谷、沒有興趣的時候還需要鞭策來幫你去學習新的不擅長的知識,
以前異步是我掌握最差的部分,在這一個階段的學習我收獲很多不知道身為讀者的你收獲了多少呢? 只有你自己知道了
異步的美妙我們就算是先告一段落。
下面的一個巨大的系列章節(jié),我將會對vuer-router源碼進行一個系統(tǒng)的學習,并且隨著學習之中產(chǎn)出文檔喲,算是繼續(xù)鞭策和與大家一塊學習。
還是那個熟悉的結(jié)束語:每一個前端coder(boy and girl)你們永遠不是一個人在戰(zhàn)斗~
新聞標題:[完結(jié)篇]-理解異步之美---promise與asyncawait(三)
鏈接分享:http://m.newbst.com/article10/jegsdo.html
成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站收錄、云服務器、品牌網(wǎng)站設計、域名注冊、響應式網(wǎng)站、商城網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)