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