亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > JS > 正文

ES6的異步終極解決方案分享

2024-05-06 16:53:15
字體:
來源:轉載
供稿:網友

前言

Promise async generator是ES6之后才被提出來的,他們都能夠用來解決以前JS異步調用產生的一系列問題,例如大名鼎鼎的回調地獄!!!

什么是回調地獄?

在以前js中,我們是無法知曉一個異步操作是否執行完成,為了在異步操作完成后執行特定的代碼,我們需要傳入回調函數,請看下面的栗子:

這是一個簡單的例子,在請求完成后(可以理解為異步操作)執行特定的代碼

 //我們需要在請求完成后輸出請求完成,請看回調法 function show(params) { request('這是請求參數', () => { console.log('請求完成') }) } /** * 模擬發起一個http請求 * @param {object} data 請求的參數 * @param {function} callBack 回調函數 */ function request(data, callBack) { //下面的定時器模擬請求時間 setTimeout(data => { callBack(data); }, 3000); } show()

一次回調當然簡單,如果是在這次請求完成后需要立即發起下一次請求呢?例如需要請求request10次,必須在上次請求完成后才能進行下一次請求,來看看 回調地獄 是怎么樣的

 //我們需要在請求完成后輸出請求完成,請看回調法 function show(params) { request('這是請求參數', () => { console.log('請求完成1次') request('這是請求參數', () => { console.log('請求完成2次') request('這是請求參數', () => {  console.log('請求完成3次')  request('這是請求參數', () => {  console.log('請求完成4次')  request('這是請求參數', () => {  console.log('請求完成5次')  //這才第五次.....  })  }) }) }) }) } /** * 模擬發起一個http請求 * @param {object} data 請求的參數 * @param {function} callBack 回調函數 */ function request(data, callBack) { //下面的定時器模擬請求時間 setTimeout(data => { callBack(data); },1000); } show()

這才第5次回調,但是代碼的可讀性已經極差了!

讓我們先看看 Promise async generator怎么解決這個問題,后面再說其使用方式

首先 Promise 篇

 //我們需要在請求完成后輸出請求完成,請看回調法 function show(params) { request('這是請求參數').then( resolve => { console.log('請求完成1次'); return request('這是請求參數') } ).then( resolve => { console.log('請求完成2次'); return request('這是請求參數') } ).then( resolve => { console.log('請求完成3次'); return request('這是請求參數') } ).then( resolve => { console.log('請求完成4次'); return request('這是請求參數') } ).then( resolve => { console.log('請求完成5次'); return request('這是請求參數') } ) } /** * 模擬發起一個http請求 * @param {object} data 請求的參數 * @param {function} callBack 回調函數 */ function request(data) { return new Promise( resolve => { //下面的定時器模擬請求時間 setTimeout(data => {  resolve(data) }, 1000); } ) } show()

雖然還是很長,但是至少嵌套很少了,可讀性也比之前更高

再來看看 async

切記,async必須和Promise配合使用

 //我們需要在請求完成后輸出請求完成,請看回調法 async function show(params) { let result = await request('這是請求參數') console.log('請求完成1次'); result = await request('這是請求參數') console.log('請求完成2次'); result = await request('這是請求參數') console.log('請求完成3次'); result = await request('這是請求參數') console.log('請求完成4次'); result = await request('這是請求參數') console.log('請求完成5次'); } /** * 模擬發起一個http請求 * @param {object} data 請求的參數 * @param {function} callBack 回調函數 */ function request(data) { return new Promise( resolve => { //下面的定時器模擬請求時間 setTimeout(data => {  resolve(data) }, 1000); } ) } show()

代碼是不是更加簡短了?而且看起來和同步一樣,事實上,這就是使用同步的方式寫異步代碼,這代碼也是同步執行的

最后看看 generator

 //我們需要在請求完成后輸出請求完成,請看回調法 function* show() { let a1 = yield request('請求參數', () => { console.log('這是第1次調用'); }); let a2 = yield request('請求參數', () => { console.log('這是第2次調用'); }); let a3 = yield request('請求參數', () => { console.log('這是第3次調用'); }); let a4 = yield request('請求參數', () => { console.log('這是第4次調用'); }); let a5 = yield request('請求參數', () => { console.log('這是第5次調用'); }); } /** * 模擬發起一個http請求 * @param {object} data 請求的參數 * @param {function} callBack 回調函數 */ function request(data, callBack) { //下面的定時器模擬請求時間 setTimeout(() => { callBack(data) }, 1000); } let a = show() a.next(); a.next(); a.next(); a.next(); a.next();

以上是異步編程的ES6解決方案,接下來讓我們把這3種方式都詳細了解下

一.Promise

關于Promise的一些原型,函數,請移步 官方鏈接

Promise的中文名,也就是承諾,保證,

大家可以將Promise理解為JS的一個承諾,也就是對異步操作的一個承諾,咱先不管異步操作是否能夠執行成功,使用Promise的所有異步操作,JS已經承諾處理了,咱就通過Promise的狀態來知曉異步操作的執行結果。

一個 Promise有以下幾種狀態:

  • pending: 初始狀態,既不是成功,也不是失敗狀態。
  • fulfilled: 表示著操作完成,狀態成功。
  • rejected: 意味著操作失敗。

pending 狀態的 Promise 對象可能會變為fulfilled 狀態并傳遞一個值給相應的狀態處理方法,也可能變為失敗狀態(rejected)并傳遞失敗信息。當其中任一種情況出現時,Promise 對象的 then 方法綁定的處理方法(handlers )就會被調用

上文提到Promise的原型中的函數then,then可以接收2個參數(resolve [,reject])

第一個參數resolve 是對成功的一個處理,類型為Function。你可以在其中做 一些異步成功后的操作

第二個參數reject是對失敗的一個處理,類型為Function。你可以在其中做 一些異步失敗后的操作

一般情況下then我們只會傳一個參數,也就是默認的成功處理,失敗處理會使用 catch函數

catch函數只有一個參數,也就是代表失敗的reject

來看看then catch的使用案例

 function show(params) { //正常的請求成功操作 request('這是請求參數').then( resolve => { console.log(resolve); } ) //在then里面同時做成功和失敗的操作 request('這是請求參數').then( resolve => { //這兒是成功 console.log(resolve); }, reject => { //這兒是失敗 console.log(reject); } ) //正常的請求失敗操作 request('這是請求參數').catch( reject => { console.log(reject); } ) } /** * 模擬發起一個http請求 * @param {object} data 請求的參數 * @param {function} callBack 回調函數 */ function request(data) { return new Promise( (resolve, reject) => { //下面的定時器模擬請求時間 setTimeout(data => {  // resolve('請求成功')  reject('請求失敗') }, 1000); } ) } show()

使用 Promise 能夠使你的異步操作變得更加優雅,可讀性也比較高,同時,Promise在ES6的各大插件中也使用的相當廣泛,所以掌握 Promise是非常有必要的

二.async / await

想詳細了解更多,請移步官方文檔

async關鍵字用來定義一個function,用來標識此函數是一個異步函數

切記 切記 切記, await 關鍵字僅僅在 async function中有效。如果在 async function函數體外使用 await ,你只會得到一個語法錯誤SyntaxError

async關鍵字放在函數的聲明之前,例如:

 async function test() { } async () => { } async data => { } class Test { async show() {  } }

無論是普通的函數,Lambda表達式,或是ES6的class,該關鍵字都是放置在函數的聲明之前

在調用聲明了async的函數時,會返回一個Promise對象

而await關鍵字則是放置在異步操作的調用之前,await會使得async函數在執行到異步操作時暫停代碼執行,直到異步操作返回的Promise狀態更改為 fulfilled 或 rejected,此時代碼會繼續執行,并自動解析Promise返回的值,無論是成功還是失敗,都會解析到await關鍵字前面定義接收的參數,請看例子:

class Test { /** * 線程休眠 * @param {number} timer 休眠毫秒數 */ Sleep(timer) { return new Promise( resolve => { setTimeout(() => {  resolve(timer) }, timer); } ) }}let T = new Test();async function show() { console.log('第一次'); await T.Sleep(1000) console.log('第二次');}show()

上面的實例調用show函數,會立即打印出 第一次,延時1000毫秒后,會打印出 第二次

原理嘛,就是模仿Java的線程休眠函數Sleep

在打印了 第一次 后,會調用T的Sleep函數,Sleep函數返回了一個Promise,在定時器執行完畢后調用Promise的resolve函數,會將Promise 的狀態更改為 fulfilled,此時await檢測到Promise的狀態更改,繼續執行代碼,輸出 第二次

三 . generator

generator(生成器)是ES6標準引入的新的數據類型,使用方式是在函數名前加上*,generator和普通的函數差不多,但是可以返回多次。

嗯,所有的函數都有默認的返回值,如果沒有明確定義,那就會返回undefined,generator也不例外!

generator使用yield關鍵字來中途返回值,請看案例

 function* a(num) { let sum = yield num + 1 console.log(sum);//2 此處是next(r.value)傳入的值 let sum2 = yield sum + 2 } let result = a(1); let r = result.next() console.log(r);//此處返回第一次yield的值 2 console.log(result.next(2));//此處返回第二次yield的值 4 console.log(result.next());//此處并沒有第三次yield

ES6,異步終極

第一次輸出的是第一次yield的值,此時num為調用a函數時傳入的值 1,yield返回了num+1,所以第一行打印的對象 value值是 2

第二次打印的是sum值,也就是第一個yield關鍵字前面接收的值,此值是下面result.next(2)傳入的 ,next函數傳入的參數,會賦值到相應的yield關鍵字左邊接收的那個變量,在上方案例,也就是sum變量

第三次輸出的是a函數中第二個yield返回的值,此時sum為第一次next(2)傳入的2,所以此次返回的值是2+2,所以值也就是 4

第四次輸出的是最后一個next(),但是上方generator并沒有相應的yield返回,所以此時的value為undefined

yield返回的值是一個對象,其中有done和value兩個屬性,

  • done 表示該generator是否執行完畢,當沒有yield返回時,done的值為true,也就是代表當前generator執行完畢
  • value表示此次yield關鍵字右方表達式返回的值,當沒有yield時,value為undefined

generator是支持迭代器操作的,例:

 function* a(num) { let sum = yield num + 1 console.log(sum);//2 此處是next(r.value)傳入的值 let sum2 = yield sum + 2 } let result = a(1); for (const key of result) { console.log(key);  }

ES6,異步終極

事實證明generator是實現了迭代器的接口的!

嗯,關于generator的實際應用場景,我是沒有遇見的,不過聽說 async/await是generator的語法糖??

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對VeVb武林網的支持。


注:相關教程知識閱讀請移步到JavaScript/Ajax教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美人在线观看| 亚洲精品有码在线| 国产精品欧美风情| 亚洲国产精品成人av| 亚洲免费视频网站| 欧美视频裸体精品| 日韩av在线免费| 国产成人精品一区二区在线| 欧美中文在线视频| 日本久久久久久久久久久| 日韩在线资源网| 国内免费精品永久在线视频| 日本亚洲欧洲色α| 中文字幕视频一区二区在线有码| 91色视频在线观看| 国产不卡视频在线| 欧美俄罗斯性视频| 亚洲国产精品热久久| 国产日韩在线免费| 欧美性xxxx在线播放| 国产精品普通话| 日韩视频第一页| 欧美精品18videos性欧美| 欧美在线观看视频| 91精品国产色综合| 欧洲成人在线观看| 国产精品久久99久久| 亚洲男人的天堂在线| 亚洲精品久久久久久久久久久| 色噜噜狠狠狠综合曰曰曰| 成人欧美在线观看| 日本一区二三区好的精华液| 亚洲成人久久一区| 国产成人综合久久| 午夜精品免费视频| 久久精品视频在线观看| 国产精品成人v| 日韩中文字幕在线观看| 中文字幕在线看视频国产欧美在线看完整| 国产精品白丝av嫩草影院| 欧美日韩国产一中文字不卡| 精品高清美女精品国产区| 日韩av在线一区二区| 中文字幕精品在线| www日韩中文字幕在线看| 亚洲成成品网站| 成人网在线免费观看| 亚洲电影成人av99爱色| 欧美精品精品精品精品免费| 国产精品va在线| 播播国产欧美激情| 国产精品第8页| 亚洲系列中文字幕| 国产精品亚洲第一区| 亚洲精品久久久久久久久久久| 日本精品免费观看| 亚洲第一网站男人都懂| 一区二区三区在线播放欧美| 国产一区二区三区在线观看视频| 久久久久久久久久久免费精品| 欧美成人国产va精品日本一级| 久久偷看各类女兵18女厕嘘嘘| 性亚洲最疯狂xxxx高清| 91av成人在线| 国产91精品最新在线播放| 国产精品美女久久| 成人一区二区电影| 日韩成人xxxx| 日韩欧美视频一区二区三区| 日本免费在线精品| 欧美肥臀大乳一区二区免费视频| 国产日韩中文字幕| 国产精品第1页| 亚洲精品国产欧美| 欧美成人小视频| 97视频网站入口| 国产午夜一区二区| 久久国产精品久久久久久| www.日韩不卡电影av| 日韩男女性生活视频| 国产亚洲欧美日韩一区二区| 疯狂欧美牲乱大交777| 日韩欧美在线播放| 欧洲亚洲妇女av| 日韩精品在线免费观看| 日韩**中文字幕毛片| 亚洲第一页自拍| 亚洲第一精品夜夜躁人人躁| 国模视频一区二区三区| 在线播放国产一区二区三区| 亚洲精品国产综合久久| 国产亚洲精品美女久久久| 国产日韩欧美在线视频观看| 富二代精品短视频| 成人a级免费视频| 18性欧美xxxⅹ性满足| 亚洲人高潮女人毛茸茸| 91av在线视频观看| 在线观看91久久久久久| 欧美三级欧美成人高清www| 成人有码在线视频| 人妖精品videosex性欧美| 欧美另类老肥妇| 日韩性生活视频| 欧美精品做受xxx性少妇| 亚洲人成电影在线| 中文字幕最新精品| 91精品久久久久久久久久入口| 亚洲电影免费在线观看| 国产精品黄色影片导航在线观看| 国产精品视频yy9099| 国产一区二区三区四区福利| 欧美一级大片在线观看| 欧美极品美女视频网站在线观看免费| 久久99精品国产99久久6尤物| 欧美在线不卡区| 国产丝袜一区二区| 黑人精品xxx一区一二区| 国产精品久久久久久一区二区| 亚洲三级av在线| 国产成人精品在线| 亚洲黄页视频免费观看| 日韩精品极品在线观看播放免费视频| 日韩在线视频观看| 久久精品国产亚洲精品| 亚洲www视频| 欧美精品在线观看| 国产精品1区2区在线观看| 亚洲天堂av综合网| 亚洲国产日韩欧美在线图片| 国语自产精品视频在线看一大j8| 亚洲国产另类久久精品| 欧美影院成年免费版| 欧美亚洲成人精品| 国产综合视频在线观看| 欧美性猛交xxxx免费看久久久| 国产婷婷97碰碰久久人人蜜臀| 成人写真视频福利网| 正在播放亚洲1区| 2019中文在线观看| 精品久久久香蕉免费精品视频| 亚洲美女又黄又爽在线观看| 色悠悠国产精品| 高清视频欧美一级| 91系列在线播放| 欧美在线观看网址综合| 欧美多人乱p欧美4p久久| 国产美女精品视频免费观看| 欧美丝袜一区二区| 国产精品美女999| 日韩三级影视基地| 亚洲精品在线视频| 国产日韩在线精品av| 原创国产精品91| 久久久久久com| 国产不卡av在线免费观看| 亚洲欧美日韩图片| 亚洲成色www8888| 成人免费视频在线观看超级碰| 精品久久久久久中文字幕| 久久国产精品网站| 韩国视频理论视频久久| 亚洲色图偷窥自拍| 欧美中文字幕在线|