摘要:前文該系列下的前幾篇文章分別對(duì)不同的幾種異步方案原理進(jìn)行解析,本文將介紹一些實(shí)際場(chǎng)景和一些常見(jiàn)的面試題。流程調(diào)度里比較常見(jiàn)的一種錯(cuò)誤是看似串行的寫(xiě)法,可以感受一下這個(gè)例子判斷以下幾種寫(xiě)法的輸出結(jié)果辨別輸出順序這類題目一般出現(xiàn)在面試題里。
前文
該系列下的前幾篇文章分別對(duì)不同的幾種異步方案原理進(jìn)行解析,本文將介紹一些實(shí)際場(chǎng)景和一些常見(jiàn)的面試題。(積累不太夠,后面想到再補(bǔ))
正文 流程調(diào)度(schedule)流程調(diào)度,最常見(jiàn)的就是繼發(fā)和并發(fā)(或者說(shuō)串行和并行)兩種類型,在日常工作里都很常見(jiàn)。接下來(lái)結(jié)合實(shí)際場(chǎng)景進(jìn)行說(shuō)明:
1. 串行執(zhí)行一系列異步操作,每一步依賴前一步的結(jié)果串行執(zhí)行的關(guān)鍵是,將每一個(gè)異步任務(wù)放到前一個(gè)異步任務(wù)的回調(diào)函數(shù)里執(zhí)行。
場(chǎng)景:一串連續(xù)的動(dòng)畫(huà),每個(gè)動(dòng)畫(huà)必須等待前一個(gè)動(dòng)畫(huà)完全執(zhí)行完,并且如果某個(gè)動(dòng)畫(huà)執(zhí)行失敗,則不繼續(xù)執(zhí)行下一個(gè)動(dòng)畫(huà)。
代碼:
// 這里假定一共要執(zhí)行5個(gè)動(dòng)畫(huà) // getAnimation 函數(shù)模擬執(zhí)行動(dòng)畫(huà) 接收參數(shù)i表述動(dòng)畫(huà)編號(hào) 返回一個(gè)promose const getAnimation = (i) => new Promise((resolve, reject) => { setTimeout(()=>{ // 隨機(jī)返回true或者false const isSuccess = Math.random() > 0.5 console.log(`第${i}個(gè)動(dòng)畫(huà)執(zhí)行`) if(isSuccess){ return resolve(isSuccess) } return reject(isSuccess) },1000) }) // 1.promise實(shí)現(xiàn) 核心就是嵌套代碼 const serialScheduleByPromise = () => { let p = Promise.resolve(true) const tasks = [] for(let i=0;i < 5; i++){ p = p.then(isSuccess=>{ if(isSuccess){ return getAnimation(i+1) } }).catch((err)=>{ return console.log(`執(zhí)行失敗`) }) } } serialScheduleByPromise() // 2.async/await實(shí)現(xiàn) const serialScheduleByAsync = async () => { try{ for(let i=0;i < 5; i++){ await getAnimation(i+1) }}catch(e){ console.log(`執(zhí)行失敗`) } } serialScheduleByAsync()
async/await的語(yǔ)法雖然沒(méi)有多帶帶解析,但是本質(zhì)就是前一篇介紹的帶自動(dòng)執(zhí)行器的generator而已,因此不再贅述
可以看到,async的寫(xiě)法代碼更簡(jiǎn)潔,而且邏輯更清晰,可讀性更強(qiáng)。
場(chǎng)景:并發(fā)讀取5個(gè)數(shù)據(jù)(為了方便 分別編號(hào)為1-5),然后按照實(shí)際讀取順序結(jié)果
const getDataById = (i) => new Promise((resolve, reject) => { // 隨機(jī)延遲一個(gè)時(shí)間返回結(jié)果, const delay = Math.floor(Math.random() * Math.floor(3000)) // 延遲時(shí)間可能為 0,1000,2000 毫秒 setTimeout(()=>{ return resolve(i) }, delay) }) // 1.promise實(shí)現(xiàn) const concurrentScheduleByPromise = ()=>{ const promises = [] const result = [] for(let i = 0;i < 5;i++){ promises[i] = getDataById(i+1) promises[i].then(i=>{ result.push(i) }) } Promise.all(promises).then(()=>{ result.forEach(id=>{ console.log(id) }) }) } concurrentScheduleByPromise() // async/await實(shí)現(xiàn) const concurrentScheduleByAsync = () => { for(let i = 0 ;i < 5; i++){ let task = async function (){ console.log(await getDataById(i+1)) } task() } } concurrentScheduleByAsync()
注意辨析這里concurrentScheduleByAsync和serialScheduleByAsync的區(qū)別,關(guān)鍵點(diǎn)是同一個(gè)async函數(shù)內(nèi)部的await才是按順序執(zhí)行。
流程調(diào)度里比較常見(jiàn)的一種錯(cuò)誤是“看似串行”的寫(xiě)法,可以感受一下這個(gè)例子:
const getPromise = (name) =>new Promise(resolve=>{ setTimeout(()=>{ console.log(name) resolve(name) },1000) }) // 判斷以下幾種寫(xiě)法的輸出結(jié)果 Promise.resolve().then(getPromise("1a")).then(getPromise("1b")).then(getPromise("1c")) Promise.resolve().then(()=>getPromise("2a")).then(()=>getPromise("2b")).then(()=>getPromise("2c")) Promise.resolve().then(getPromise("3a").then(getPromise("3b").then(getPromise("3c")))) Promise.resolve().then(()=>getPromise("4a").then(()=>getPromise("4b").then(()=>getPromise("4c"))))辨別輸出順序
這類題目一般出現(xiàn)在面試題里。
1. 基礎(chǔ)-區(qū)分不同任務(wù)類型console.log(1) new Promise(resolve => { console.log(2) setTimeout(() => { console.log(10) }, 10) resolve() console.log(3) }).then(() => { console.log(5) }) setTimeout(() => { console.log(7) Promise.resolve().then(() => { console.log(9) }) console.log(8) }) Promise.resolve().then(() => { console.log(6) }) console.log(4) // 輸出 1 2 3 4 5 6 7 8 9 102. 復(fù)雜-加入瀏覽器render
outerinner
這類問(wèn)題實(shí)質(zhì)上就是辨析異步任務(wù)隊(duì)列類型,詳細(xì)內(nèi)容和解析可以直接看js異步從入門(mén)到放棄(三)- 異步任務(wù)隊(duì)列(task queues)。
小結(jié)這篇文章主要是給這個(gè)系列做個(gè)簡(jiǎn)單的收尾,多帶帶純異步的問(wèn)題難點(diǎn)其實(shí)也不多,偷個(gè)懶,后面想到了再補(bǔ)上。
如果覺(jué)得寫(xiě)得不好/有錯(cuò)誤/表述不明確,都?xì)g迎指出
如果有幫助,歡迎點(diǎn)贊和收藏,轉(zhuǎn)載請(qǐng)征得同意后著明出處。如果有問(wèn)題也歡迎私信交流,主頁(yè)有郵箱地址
如果覺(jué)得作者很辛苦,也歡迎打賞~
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/104654.html
摘要:特意對(duì)前端學(xué)習(xí)資源做一個(gè)匯總,方便自己學(xué)習(xí)查閱參考,和好友們共同進(jìn)步。 特意對(duì)前端學(xué)習(xí)資源做一個(gè)匯總,方便自己學(xué)習(xí)查閱參考,和好友們共同進(jìn)步。 本以為自己收藏的站點(diǎn)多,可以很快搞定,沒(méi)想到一入?yún)R總深似海。還有很多不足&遺漏的地方,歡迎補(bǔ)充。有錯(cuò)誤的地方,還請(qǐng)斧正... 托管: welcome to git,歡迎交流,感謝star 有好友反應(yīng)和斧正,會(huì)及時(shí)更新,平時(shí)業(yè)務(wù)工作時(shí)也會(huì)不定期更...
摘要:跨域請(qǐng)求詳解從繁至簡(jiǎn)前端掘金什么是為什么要用是的一種使用模式,可用于解決主流瀏覽器的跨域數(shù)據(jù)訪問(wèn)的問(wèn)題。異步編程入門(mén)道典型的面試題前端掘金在界中,開(kāi)發(fā)人員的需求量一直居高不下。 jsonp 跨域請(qǐng)求詳解——從繁至簡(jiǎn) - 前端 - 掘金什么是jsonp?為什么要用jsonp?JSONP(JSON with Padding)是JSON的一種使用模式,可用于解決主流瀏覽器的跨域數(shù)據(jù)訪問(wèn)的問(wèn)題...
摘要:今天同學(xué)去面試,做了兩道面試題全部做錯(cuò)了,發(fā)過(guò)來(lái)給道典型的面試題前端掘金在界中,開(kāi)發(fā)人員的需求量一直居高不下。 排序算法 -- JavaScript 標(biāo)準(zhǔn)參考教程(alpha) - 前端 - 掘金來(lái)自《JavaScript 標(biāo)準(zhǔn)參考教程(alpha)》,by 阮一峰 目錄 冒泡排序 簡(jiǎn)介 算法實(shí)現(xiàn) 選擇排序 簡(jiǎn)介 算法實(shí)現(xiàn) ... 圖例詳解那道 setTimeout 與循環(huán)閉包的經(jīng)典面...
摘要:在標(biāo)簽中添加屬性,本質(zhì)上是跟在標(biāo)簽里面寫(xiě)屬性時(shí)一樣的,所以屬性值最終都會(huì)編譯為字符串類型。這個(gè)節(jié)點(diǎn)包括很多,比如,以及一些方法等方法。一個(gè)對(duì)象有很多,該集合名字為,里面有其他以及,里面有很多。 一、變量類型和計(jì)算 JS中使用typeof能得到哪些類型 變量類型 值類型:變量本身就是含有賦予給它的數(shù)值的,它的變量本身及保存的數(shù)據(jù)都存儲(chǔ)在棧的內(nèi)存塊當(dāng)中 引用類型:引用類型當(dāng)然是分配到...
摘要:前言一直混跡社區(qū)突然發(fā)現(xiàn)自己收藏了不少好文但是管理起來(lái)有點(diǎn)混亂所以將前端主流技術(shù)做了一個(gè)書(shū)簽整理不求最多最全但求最實(shí)用。 前言 一直混跡社區(qū),突然發(fā)現(xiàn)自己收藏了不少好文但是管理起來(lái)有點(diǎn)混亂; 所以將前端主流技術(shù)做了一個(gè)書(shū)簽整理,不求最多最全,但求最實(shí)用。 書(shū)簽源碼 書(shū)簽導(dǎo)入瀏覽器效果截圖showImg(https://segmentfault.com/img/bVbg41b?w=107...
閱讀 2205·2021-09-22 10:56
閱讀 1496·2021-09-07 10:11
閱讀 1816·2019-08-30 15:54
閱讀 2304·2019-08-30 15:44
閱讀 2320·2019-08-29 12:40
閱讀 3040·2019-08-28 18:25
閱讀 1754·2019-08-26 10:24
閱讀 3201·2019-08-23 18:39