前端最基礎的就是 HTML+CSS+Javascript
。掌握了這三門技術就算入門,但也僅僅是入門,如今前端開發的定義已經遠遠不止這些。前端小課堂(HTML/CSS/JS
),本着提高技術水平,打牢基礎知識的中心思想,咱們開課啦(每週四)。css
上一篇是使人吐槽的ES6,這一篇就有意思的多了。
異步操做咱們不陌生,瀏覽器的UI事件、AJAX、Worker、setTimeout、setInterval 等等都是異步操做。
那麼在執行異步操做時咱們都會放入一個回調,這裏有個名詞叫什麼來着?回調地獄。
哈哈當咱們用 Promise 來處理的時候就簡潔多了,能夠鏈式操做。前端
舉個栗子吧,請求 A,用 A 的響應去請求 B,用 B 的響應去渲染到頁面上。git
代碼寫下面了,思考幾個問題es6
jQuery
中依賴 Deferred
實現。github
$.ajax({ url: 'https://www.lilnong.top/cors/A', success(data){ $.ajax({ url: 'https://www.lilnong.top/cors/B', data, success(data){ $('body').text(JSON.stringify(data,null,4)); } }) } })
$.ajax({ url: 'https://www.lilnong.top/cors/A'}) .then((data)=> $.ajax({url: 'https://www.lilnong.top/cors/B',data}) ) .then((data)=> $('body') .css('white-space', 'pre-wrap') .text(JSON.stringify(data,null,8)) )
new Promise(function(resolve, reject) {...});
同步調用 function
,裏面能夠是執行同步的,也能夠執行異步的。面試
Promise狀態
初始狀態爲 pending
當邏輯執行完以後調用 resolve(data)
(成功)、reject
(失敗)來表示計算完成
調用以後 Promise 的狀態會改變爲 resolved
(完成)、rejected
(失敗)。
若是內部拋出異常,也會進入 rejected
狀態。ajax
new Promise((resolve, reject)=>{ var start_time = Date.now(); var dtime = Math.random()*1000; setTimeout(()=>{ var end_time = Date.now(); var query_time = end_time - start_time reject({start_time,dtime,end_time,query_time,now: Date.now()}) resolve({start_time,dtime,end_time,query_time,now: Date.now()}) console.log('promise', {start_time,dtime,end_time,query_time,now: Date.now()}) return 'promise-return' }, dtime) }) .then(v=>console.log('then',v)) .catch(v=>console.log('catch',v)) window.addEventListener('unhandledrejection',e=>console.log('event',e))
狀態不會被改變
json
function
中 return
的沒有被使用。resolve
、reject
並不會退出當前做用域,會繼續執行下面的代碼。resolve
、reject
執行以後,狀態和值就不會再被改變。即便報錯都不會改變resolve
、reject
執行以後,回調被放入微任務隊列。reject
狀態沒有被 catch
捕獲,那麼會觸發 unhandledrejection
。返回一個新的 Promise 對象,根據 array 的結果來返回內容。segmentfault
當隊列中全部的 Promise 都成功纔會觸發成功。返回一個新的 Promise 對象,參數是個數組,是對應 Promise 的返回值。順序是一 一對應的,和完成時間不要緊。數組
當隊列中有任何一個 Promise 失敗則當即觸發失敗。返回一個新的 Promise 對象。Promise.all(Array) 返回一個 Promise 對象。
假設 PromiseAll = Promise.all(PromiseArray)
如下表格爲 PromiseAll 在不一樣環境下的 不一樣狀態與值。
PromiseAll 狀態 | PromiseAll 值 | |
---|---|---|
全部 Promise 都成功 |
resolved | 按原數組順序 組成的 promise 返回值集合 |
有一個 Promise 失敗 |
rejected | 第一個失敗的 Promise 的報錯信息 |
依賴這個方法咱們能夠解決前言中提出的問題,處理並行場景。
返回一個新的 Promise 對象,根據 array 的結果來返回內容。
當隊列中任意一個 Promise 的狀態變爲完成狀態(成功 resolved、失敗 rejected),則返回該 Promise。
依賴這個方法咱們能夠解決前言中提出的問題,處理競爭場景。
返回一個狀態爲失敗的 Promise 對象。
返回一個狀態由 value 決定的 Promise 對象。
若是 value 是個 Promise 對象,那麼返回的就是該 Promise 對象。若是 value 不是 Promise 對象,那麼返回就是一個成功狀態的 Promise,值爲 value。
若是你不知道一個值是否是 Promise 對象,使用Promise.resolve(value) 來返回一個 Promise 對象,這樣就能安全的將該值當作 Promise 來使用了。
當 Promise 失敗時會調用。
return 返回值的會做爲 resolve 狀態繼續傳遞。
resolve 狀態時會執行 onFulfilled 回調。
rejected 狀態時會執行 onRejected 回調。若是沒有 onRejected 回調 那麼錯誤信息繼續傳遞。
return 返回值的會做爲 resolve 狀態繼續傳遞。
resolve 和 rejected 狀態都會調用回調。可是有不一樣點
其實能夠當作 try{}catch(e){} finally{}
中 finally
來使用
await
操做符用於等待一個 Promise
對象。 await
只能在異步函數 async function
中使用。
上述的 Promise 只是把回調嵌套改爲鏈式扁平化,可是看上去仍是怪怪的,咱們能夠用 await 再處理一下 Promise。
var data = await fetch('https://www.lilnong.top/cors/A').then(v=>v.json()) var dataB = await fetch('https://www.lilnong.top/cors/B?'+new URLSearchParams(data)).then(v=>v.json()) console.log(dataB)
是否是看上去好理解多了。
https://www.zhihu.com/question/49718514
這個我感受是標題黨蹭熱度吧。。
主要說下面這個例子是地獄,固然,你一看這不是就上面那個例子嗎?不就是串行執行嗎(對,有的人並行的時候也這樣寫)?
console.log(startTime = Date.now()) dataA = await fetch('/') console.log(Date.now(), Date.now()-startTime) dataB = await fetch('/') console.log(Date.now(), Date.now()-startTime)
並行解決方案
console.log(startTime = Date.now()) dataA = fetch('/') console.log(Date.now(), Date.now()-startTime) dataB = fetch('/') await dataA await dataB console.log(Date.now(), Date.now()-startTime)
爬一篇文章 https://p.51vv.com/vp/h/hot,遇到圖片要下載,而後上傳到服務器,用服務器返回的回填,執行完成輸出文章JSON。
上面是須要實現的功能,下面來提提限制。