摘要:到這里,我已經(jīng)發(fā)出了一個(gè)請(qǐng)求買漢堡,啟動(dòng)了一次交易。但是做漢堡需要時(shí)間,我不能馬上得到這個(gè)漢堡,收銀員給我一個(gè)收據(jù)來(lái)代替漢堡。到這里,收據(jù)就是一個(gè)承諾保證我最后能得到漢堡。
同期異步系列文章推薦
談一談javascript異步
javascript異步中的回調(diào)
javascript異步之Promise.all()、Promise.race()、Promise.finally()
javascript異步之Promise.resolve()、Promise.reject()
javascript異步之Promise then和catch
javascript異步之a(chǎn)sync(一)
javascript異步之a(chǎn)sync(二)
javascript異步實(shí)戰(zhàn)
javascript異步總結(jié)歸檔
我們說(shuō)處理javascript異步最常用的方式就是通過(guò)回調(diào)函數(shù),對(duì)于回調(diào)函數(shù)我們昨天對(duì)此做了介紹
簡(jiǎn)單快速,
我們一般使用嵌套回調(diào)或者鏈?zhǔn)交卣{(diào),會(huì)產(chǎn)生以下問(wèn)題
當(dāng)采用嵌套回調(diào)時(shí),會(huì)導(dǎo)致層級(jí)太多,不利于維護(hù)
所以我們又采用了鏈?zhǔn)交卣{(diào),對(duì)嵌套回調(diào)進(jìn)行拆分,拆分后的函數(shù)間耦合度很高,
如果需要傳遞參數(shù),函數(shù)之間的關(guān)聯(lián)性會(huì)更高,而且要對(duì)參數(shù)進(jìn)行校驗(yàn)以提高代碼的健壯性
如果將我們自己的回調(diào)函數(shù)傳遞給第三方插件或者庫(kù),就要考慮一些不可控因素
調(diào)用回調(diào)過(guò)早
調(diào)用回調(diào)過(guò)晚(或不被調(diào)用)
調(diào)用回調(diào)次數(shù)過(guò)多或者過(guò)少
promise的存在就是為了解決以上問(wèn)題
雖然我們?nèi)粘懟卣{(diào)函數(shù)不會(huì)有這么嚴(yán)格的要求,但是如果不這樣去寫回調(diào)函數(shù),就會(huì)存在隱患,當(dāng)在團(tuán)隊(duì)協(xié)作的時(shí)候,顯得編碼規(guī)范顯得尤為重要
本文不重點(diǎn)介紹如何使用promise,重點(diǎn)介紹的是promise解決了哪些異步回調(diào)出現(xiàn)的問(wèn)題。
什么是promise我們來(lái)看一個(gè)場(chǎng)景,有助于我們了解promise
設(shè)想一下這個(gè)場(chǎng)景,我去KFC,交給收銀員10元,下單買一個(gè)漢堡,下單付款。到這里,我已經(jīng)發(fā)出了一個(gè)請(qǐng)求(買漢堡),啟動(dòng)了一次交易。
但是做漢堡需要時(shí)間,我不能馬上得到這個(gè)漢堡,收銀員給我一個(gè)收據(jù)來(lái)代替漢堡。到這里,收據(jù)就是一個(gè)承諾(promise),保證我最后能得到漢堡。
所以我需要好好的保留的這個(gè)收據(jù),對(duì)我來(lái)說(shuō),收據(jù)就是漢堡,雖然這張收據(jù)不能吃,我需要等待漢堡做好,等待收銀員叫號(hào)通知我
等待的過(guò)程中,我可以做些別的事情
收銀員終于叫到了我的號(hào),我用收據(jù)換來(lái)了漢堡
當(dāng)然還有一種情況,當(dāng)我去柜臺(tái)取漢堡的時(shí)候,收銀員告訴我漢堡賣光了,做漢堡的師傅受傷了等等原因,導(dǎo)致了我無(wú)法得到這個(gè)漢堡
雖然我有收據(jù)(承諾),但是可能得到漢堡(成功),可能得不到漢堡(失?。?br>我由等待漢堡變成了等到或者等不到,這個(gè)過(guò)程不可逆,
上面很形象的介紹了promise,上面的等待漢堡和得到漢堡,漢堡賣光了,得不到漢堡,分別對(duì)應(yīng)promise的三種狀態(tài)
三種狀態(tài):pending(進(jìn)行中)、fulfilled(已成功)和rejected(已失敗)(一旦狀態(tài)改變,就不會(huì)再變)
調(diào)用過(guò)早就是將異步函數(shù)作為同步處理了,
我們之前說(shuō)過(guò),javascript以單線程同步的方式執(zhí)行主線程,遇到異步會(huì)將異步函數(shù)放入到任務(wù)隊(duì)列中,
當(dāng)主線程執(zhí)行完畢,會(huì)循環(huán)執(zhí)行任務(wù)隊(duì)列中的函數(shù),也就是事件循環(huán),直到任務(wù)隊(duì)列為空。
事件循環(huán)就像是一個(gè)游樂(lè)場(chǎng),玩過(guò)一個(gè)游戲后,你需要重新排到隊(duì)尾才能再玩一次
任務(wù)隊(duì)列就是,在你玩過(guò)一個(gè)游戲后,可以插隊(duì)接著玩
我們看一個(gè)栗子
const promise = new Promise((resolve, reject) => { resolve("成功啦") }); promise.then(res => { console.log(res); console.log("我是異步執(zhí)行的"); }) console.log("我在主線程");
看下輸出,重點(diǎn)看輸出順序
//我在主線程 //成功啦 //我是異步執(zhí)行的
直接手動(dòng)是promise的狀態(tài)切為成功狀態(tài),console.log("我是異步執(zhí)行的");這段代碼也是異步執(zhí)行的
提供給then()的回調(diào)永遠(yuǎn)都是異步執(zhí)行的,所以promise中不會(huì)出現(xiàn)回調(diào)函數(shù)過(guò)早執(zhí)行的情況
回調(diào)函數(shù)調(diào)用過(guò)晚的處理原理和調(diào)用過(guò)早很類似,
在promise的then()中存放著異步函數(shù),所有的異步都存在于js的任務(wù)隊(duì)列中,當(dāng)js的主線程執(zhí)行完畢后,會(huì)依次執(zhí)行任務(wù)隊(duì)列中的內(nèi)容,不會(huì)出現(xiàn)執(zhí)行過(guò)晚的情況
我們用栗子說(shuō)話
const promise = new Promise((resolve, reject) => resolve("成功啦")) promise.then(s => console.log(s)); console.log("我在主線程");
成功狀態(tài)的輸出
//我在主線程 //成功啦
成功狀態(tài)下回調(diào)被調(diào)用
繼續(xù)看一下失敗的回調(diào)
const promise = new Promise((resolve, reject) => reject("失敗啦")) promise.then(null, s => console.log(s)); console.log("我在主線程");
失敗狀態(tài)的輸出
//我在主線程 //失敗啦
失敗狀態(tài)下回調(diào)被調(diào)用
所以說(shuō),不管是失敗還是成功,回調(diào)函數(shù)都會(huì)被調(diào)用
我們之前說(shuō)了promise有三種狀態(tài)
pending(進(jìn)行中)、fulfilled(已成功)和rejected(已失敗)狀態(tài)一旦狀態(tài)改變,就不會(huì)再變
一個(gè)栗子
const promise = new Promise((resolve, reject) => { reject("失敗啦") resolve("成功啦") }); promise.then(res => { console.log(`我是異步執(zhí)行的成功:${res}`); },err=>{ console.log(`我是異步執(zhí)行的失敗:${err}`); }).catch(err => { console.log(err); }) console.log("我在主線程");
輸出
//我在主線程 //我是異步執(zhí)行的失敗:失敗啦
當(dāng)狀態(tài)變?yōu)槭r(shí),就不會(huì)再變?yōu)槌晒Γ晒Φ暮瘮?shù)也不會(huì)執(zhí)行,反之亦然
調(diào)用次數(shù)過(guò)少回調(diào)函數(shù)正常是調(diào)用一次,過(guò)少=>0次=>回調(diào)函數(shù)不被調(diào)用,上面剛剛討論過(guò)
原文鏈接
參考鏈接
JavaScript Promise 迷你書
Promise 對(duì)象
ES6 系列之我們來(lái)聊聊 Promise
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/101268.html
摘要:從最開始的到封裝后的都在試圖解決異步編程過(guò)程中的問(wèn)題。為了讓編程更美好,我們就需要引入來(lái)降低異步編程的復(fù)雜性。寫一個(gè)符合規(guī)范并可配合使用的寫一個(gè)符合規(guī)范并可配合使用的理解的工作原理采用回調(diào)函數(shù)來(lái)處理異步編程。 JavaScript怎么使用循環(huán)代替(異步)遞歸 問(wèn)題描述 在開發(fā)過(guò)程中,遇到一個(gè)需求:在系統(tǒng)初始化時(shí)通過(guò)http獲取一個(gè)第三方服務(wù)器端的列表,第三方服務(wù)器提供了一個(gè)接口,可通過(guò)...
摘要:的翻譯文檔由的維護(hù)很多人說(shuō),阮老師已經(jīng)有一本關(guān)于的書了入門,覺得看看這本書就足夠了。前端的異步解決方案之和異步編程模式在前端開發(fā)過(guò)程中,顯得越來(lái)越重要。為了讓編程更美好,我們就需要引入來(lái)降低異步編程的復(fù)雜性。 JavaScript Promise 迷你書(中文版) 超詳細(xì)介紹promise的gitbook,看完再不會(huì)promise...... 本書的目的是以目前還在制定中的ECMASc...
摘要:為這些回調(diào)函數(shù)分別命名并分離存放可以在形式上減少嵌套,使代碼清晰,但仍然不能解決問(wèn)題。如果在一個(gè)結(jié)束成功或失敗,同前面的說(shuō)明后,添加針對(duì)成功或失敗的回調(diào),則回調(diào)函數(shù)會(huì)立即執(zhí)行。 異步? 我在很多地方都看到過(guò)異步(Asynchronous)這個(gè)詞,但在我還不是很理解這個(gè)概念的時(shí)候,卻發(fā)現(xiàn)自己常常會(huì)被當(dāng)做已經(jīng)很清楚(* ̄? ̄)。 如果你也有類似的情況,沒關(guān)系,搜索一下這個(gè)詞,就可以得到大致...
摘要:的執(zhí)行與狀態(tài)無(wú)關(guān)當(dāng)?shù)玫綘顟B(tài)不論成功或失敗后就會(huì)執(zhí)行,原文鏈接參考鏈接對(duì)象 同期異步系列文章推薦談一談javascript異步j(luò)avascript異步中的回調(diào)javascript異步與promisejavascript異步之Promise.resolve()、Promise.reject()javascript異步之Promise then和catchjavascript異步之a(chǎn)sync...
摘要:最受歡迎的引擎是,在和中使用,用于,以及所使用的。怎么處理每個(gè)引擎都有一個(gè)基本組件,稱為調(diào)用棧。也就是說(shuō),如果有其他函數(shù)等待執(zhí)行,函數(shù)是不能離開調(diào)用棧的。每個(gè)異步函數(shù)在被送入調(diào)用棧之前必須通過(guò)回調(diào)隊(duì)列。例如方法是在中傳遞的回調(diào)函數(shù)。 ? 翻譯:瘋狂的技術(shù)宅 原文:www.valentinog.com/blog/engine… 從Call Stack,Global Me...
閱讀 3037·2020-01-08 12:17
閱讀 2004·2019-08-30 15:54
閱讀 1160·2019-08-30 15:52
閱讀 2046·2019-08-29 17:18
閱讀 1056·2019-08-29 15:34
閱讀 2469·2019-08-27 10:58
閱讀 1871·2019-08-26 12:24
閱讀 385·2019-08-23 18:23