摘要:常見問題總結(jié)如何中斷的缺點之一就是無法讓中斷如上代碼如何讓的鏈?zhǔn)秸{(diào)用中斷一種方法是在中直接拋錯這樣就不會執(zhí)行直接跳到方法打印但此方法并沒有實際中斷另一種方法就是在中一個新的但不改變其狀態(tài)這樣該就一直處于狀態(tài)即不會執(zhí)行后面任何方法中斷有啥用
promise常見問題總結(jié) promise如何中斷
promise的缺點之一就是無法讓promise中斷
Promise.resolve().then(() => { console.log("then 1") }).then(() => { console.log("then 2") }).then(() => { console.log("then 3") }).catch((err) => { console.log(err) })
如上代碼如何讓promise的鏈?zhǔn)秸{(diào)用中斷?
一種方法是在then 1中直接拋錯, 這樣就不會執(zhí)行then 2, then 3, 直接跳到catch方法打印err(但此方法并沒有實際中斷)
Promise.resolve().then(() => { console.log("then 1") throw new Error("xxx") }).then(() => { console.log("then 2") }).then(() => { console.log("then 3") }).catch((err) => { console.log(err) })
另一種方法就是在then 1中return 一個新的Promise,但不改變其狀態(tài),這樣該Promise就一直處于pedding狀態(tài),即不會執(zhí)行后面任何方法
Promise.resolve().then(() => { console.log("then 1") return new Promise(() => {}) }).then(() => { console.log("then 2") }).then(() => { console.log("then 3") }).catch((err) => { console.log(err) })
中斷有啥用? ---------- 可以讓我想到超時中斷問題
假設(shè)我們要用promsie自己封裝一個ajax, 設(shè)置超時中斷時間,如果沒返回就不用返回了, 返回也不做處理了,不重要(雖然和上面的原理沒關(guān)系,但不重要,上面是一個promsie的鏈?zhǔn)秸{(diào)用中斷,此例是實際應(yīng)用中的問題,你管我用幾個promsie呢, 想到了記錄一下)
function wrap(p1) { let abort let p2 = new Promise((resolve, reject) => { abort = reject }) let p = Promise.race([p1, p2]) // 將延時promise的reject方法掛在到p1與p2的race后的promise上, 可以在方法外通過調(diào)用p的cancel方法,來觸發(fā)p2的reject p.cancel = abort return p } let fn = wrap(new Promise((resolve, reject) => { // 假設(shè)1秒后ajax返回, 調(diào)用resolve setTimeout(() => { resolve() }, 1000) })) fn.then(() => { console.log("ok") }).catch(() => { console.log("err") }) // 設(shè)置延時時間500ms, 如果500ms數(shù)據(jù)買回來,就中斷 setTimeout(() => { fn.cancel() }, 500)promise 微任務(wù)的執(zhí)行順序
之前的promise中斷好歹還可以強說有點用,下面這種例子,誰要是沒事寫在生產(chǎn)代碼中,直接開除好吧~~~尋思尋思得了
const p = Promise.resolve(); ;(()=>{ const implicit_promise = new Promise(resolve =>{ const promise = new Promise(resolve=>{ resolve(p) }); promise.then(()=>{ console.log("after:await"); resolve() }) }); return implicit_promise })(); p.then(()=>{ console.log("tick:a"); }).then(()=>{ console.log("tick:b"); }).then(()=>{ console.log("tick:c"); });
首先第一行生成一個resolve成功態(tài)的promise,然后自執(zhí)行函數(shù)同步代碼直接執(zhí)行,
第5行resolve(p), 這里要知道resolve一個promsie要等到該promise執(zhí)行then方法后才能拿到返回值
也就是說第7行的then要等到p的返回值拿到之后才執(zhí)行
下面先把下面的鏈?zhǔn)骄幊滩鹨幌?/p>
const p = Promise.resolve(); ;(()=>{ const implicit_promise = new Promise(resolve =>{ const promise = new Promise(resolve=>{ resolve(p) }); promise.then(()=>{ console.log("after:await"); resolve() }) }); return implicit_promise })(); let p1 = p.then(()=>{ console.log("tick:a"); }) p1.then(()=>{ console.log("tick:b"); }).then(()=>{ console.log("tick:c"); });
自執(zhí)行函數(shù)執(zhí)行完,執(zhí)行p1的回調(diào)先打印tick:a,且由于沒有return值,所以默認return一個新的promise也就是p1接收的心promise
然后緊接著p1調(diào)用then方法,之后第7行也調(diào)用then方法, 所以相繼打印tick:b和after:await
等到tick:b執(zhí)行完返回一個新的promise,這才執(zhí)行tick:c
所以打印順序為 tick:a ==> tick:b ==> after:await ==> tick:c
這就是面向面試學(xué)習(xí)的精髓
async function async1(){ console.log("async1 start") await async2(); console.log("async1 end") } async function async2(){ console.log("async2") } console.log("script start") setTimeout(function(){ console.log("setTimeout") },0) async1(); new Promise(function(resolve){ console.log("promise1") resolve(); }).then(function(){ console.log("promise2") }) console.log("script end");
這段代碼在很多地方看到了,其他執(zhí)行順序很容易理解,唯一的問題就在于async1 end什么時候執(zhí)行,我們先不考慮這行console
就很容易可以得到以下結(jié)果
// script start (同步代碼,上面是兩個函數(shù)還沒有調(diào)用) // async1 start (調(diào)用async1的時候執(zhí)行async1函數(shù),打印async1 start) // async2 (在async1中調(diào)用async2, 打印async2) // promsie1 (同步代碼執(zhí)行到new Promise, 在executor中執(zhí)行同步代碼, 打印promise1) // script end (promise1 打印后暫不執(zhí)行promsie2因為then回調(diào)是在微任務(wù)中,先執(zhí)行同步代碼, 打印script end) // promise2 (同步代碼執(zhí)行完, 清空微任務(wù)) // setTimeout (宏任務(wù)執(zhí)行)
那么問題就在于async1 end什么時候執(zhí)行
毫無疑問現(xiàn)在的問題在于await的原理,他肯定也是異步的微任務(wù), 問題在于async1 end和promise2 誰先執(zhí)行,
首先在node環(huán)境下測試是promise2先執(zhí)行,但是在chrome中執(zhí)行是async1 end先執(zhí)行
由此可以得出await轉(zhuǎn)化promise
在node中
async2().then(() => { console.log("async1 end") }) // 你以為是這么轉(zhuǎn)化的?我也是這么以為的,**但是**在node中的then函數(shù)中它默認用Promise又包裹一層所以是這樣的 async2().then(() => { return Promise.resolve().then(() => { console.log("async1 end") }) }) // 有點惡心了~~~我測試的版本是v8.6.0以上版本 // 這樣的執(zhí)行順序就是async1 end 在promise2之后 // script start // async1 start // async2 // promise1 // script end // promise2 // async1 end // setTimeout
但在chrome(74.0.3729.169)中的轉(zhuǎn)化應(yīng)該是只有一個then,then中直接調(diào)用console,所以在瀏覽器中就是
// script start // async1 start // async2 // promise1 // script end // async1 end // promise2 // setTimeout
這個轉(zhuǎn)化過程是通過結(jié)果推出來的,總之開發(fā)環(huán)境還是要避免這樣的代碼出現(xiàn)
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/104934.html
摘要:引擎線程也稱為內(nèi)核,負責(zé)處理腳本程序例如引擎引擎線程負責(zé)解析腳本,運行代碼。對象代表一個未完成但預(yù)計將來會完成的操作。注意一旦新建就會立即執(zhí)行它屬于,無法取消。 寫在前面: 第一遍學(xué)Promise時, 只是大概過了一遍, 感覺學(xué)的不夠深入, 這一篇算是對之前的一個總結(jié)吧. Promise在ES6中也屬于一個較難理解的一部分; 所以在學(xué)習(xí)一個比較難理解的知識點時, 我們可以圍繞這個知識點...
摘要:眾所周知和都屬于上述異步任務(wù)的一種那到底為什么和會有順序之分這就是我想分析總結(jié)的問題所在了和的作用是為了讓瀏覽器能夠從內(nèi)部獲取的內(nèi)容并確保執(zhí)行棧能夠順序進行。只要執(zhí)行棧沒有其他在執(zhí)行,在每個結(jié)束時,隊列就會在回調(diào)后處理。 前言 我是在做前端面試題中看到了setTimeout和Promise的比較,然后第一次看到了microtask和macrotask的概念,在閱讀了一些文章之后發(fā)現(xiàn)沒有...
摘要:那個率先改變的實例的返回值,就會傳遞給的回調(diào)函數(shù)。函數(shù)對函數(shù)的改進,體現(xiàn)在以下四點內(nèi)置執(zhí)行器。進一步說,函數(shù)完全可以看作多個異步操作,包裝成的一個對象,而命令就是內(nèi)部命令的語法糖。中的本質(zhì)就是沒有的隱藏的組件。 1、原型 - jquery使用showImg(https://segmentfault.com/img/bVbwNcY?w=692&h=442);注釋 : 實例雖然不同,但是構(gòu)...
摘要:的翻譯文檔由的維護很多人說,阮老師已經(jīng)有一本關(guān)于的書了入門,覺得看看這本書就足夠了。前端的異步解決方案之和異步編程模式在前端開發(fā)過程中,顯得越來越重要。為了讓編程更美好,我們就需要引入來降低異步編程的復(fù)雜性。 JavaScript Promise 迷你書(中文版) 超詳細介紹promise的gitbook,看完再不會promise...... 本書的目的是以目前還在制定中的ECMASc...
摘要:以下總結(jié)了異步編程的種方式回調(diào)函數(shù)回調(diào)函數(shù)異步編程的最基本的方式。由小組的成員在規(guī)范中提出,目的是為異步編程提供統(tǒng)一接口。結(jié)尾參考文章異步編程參考文章使用詳解 前言 Javascript語言的執(zhí)行環(huán)境是單線程。 單線程: 一次只能完成一個任務(wù)。如果有多個任務(wù),就必須排隊,前面一個任務(wù)完成,再執(zhí)行后面一個任務(wù)。 單線程的好處是執(zhí)行環(huán)境簡單,壞處是在一些耗時的任務(wù)上會堵塞進程。比如讀取一個...
閱讀 3669·2021-11-23 09:51
閱讀 1661·2021-10-22 09:53
閱讀 1345·2021-10-09 09:56
閱讀 853·2019-08-30 13:47
閱讀 2155·2019-08-30 12:55
閱讀 1597·2019-08-30 12:46
閱讀 1105·2019-08-30 10:51
閱讀 2410·2019-08-29 12:43