成人怡红院-成人怡红院视频在线观看-成人影视大全-成人影院203nnxyz-美女毛片在线看-美女免费黄

站長資訊網(wǎng)
最全最豐富的資訊網(wǎng)站

一文帶你輕松掌握Promise

一文帶你輕松掌握Promise

前端js學(xué)習(xí)中,讓大家最難受的就是異步的問題,解決異步、回調(diào)地獄等問題時你必須得學(xué)會promise,對于多數(shù)前端程序員來說promise簡直就是噩夢,本篇文章就是從通俗易懂的角度做為切入點(diǎn),幫助大家輕松掌握promise

異步編程


想要學(xué)習(xí)promise,你必須要懂得什么是異步編程!眾所周知,js語言是單線程機(jī)制。所謂單線程就是按次序執(zhí)行,執(zhí)行完一個任務(wù)再執(zhí)行下一個。但是不影響存在同步異步的兩種操作,這兩種操作做事情其實(shí)都是在一條流水線上(單線程),只是這兩種操作在單線程上的執(zhí)行順序不一樣罷了!當(dāng)js觸發(fā)到異步任務(wù)時,會將異步任務(wù)交給瀏覽器處理,當(dāng)執(zhí)行有結(jié)果時,會把異步任務(wù)的回調(diào)函數(shù)插入待處理隊(duì)列的隊(duì)尾!

我們通俗的去解釋一下我們的異步:異步就是從主線程發(fā)射一個子線程來完成任務(wù),每一個任務(wù)有一個或多個回調(diào)函數(shù)(callback),前一個任務(wù)結(jié)束后,不是執(zhí)行后一個任務(wù),而是執(zhí)行回調(diào)函數(shù)后一個任務(wù)則是不等前一個任務(wù)結(jié)束就執(zhí)行,所以程序的執(zhí)行順序與任務(wù)的排列順序是不一致的、異步的.

一文帶你輕松掌握Promise

該圖摘自于菜鳥教程中的異步編程小節(jié),幫助大家更好的理解什么是異步!

回調(diào)函數(shù)


回調(diào)函數(shù)的定義非常簡單:一個函數(shù)被當(dāng)做一個實(shí)參傳入到另一個函數(shù)(外部函數(shù)),并且這個函數(shù)在外部函數(shù)內(nèi)被調(diào)用,用來完成某些任務(wù)的函數(shù)。就稱為回調(diào)函數(shù)

回調(diào)函數(shù)的兩種寫法(實(shí)現(xiàn)效果相同):

const text = () => { 	   document.write('hello james') } setTimeout(text,1000)
登錄后復(fù)制

setTimeout(()=>{ 	   document.write("hello james") },1000)
登錄后復(fù)制

這段代碼中的 setTimeout 就是一個消耗時間較長的過程,它的第一個參數(shù)是個回調(diào)函數(shù),第二個參數(shù)是毫秒數(shù),這個函數(shù)執(zhí)行之后會產(chǎn)生一個子線程,子線程會等待 1 秒,然后執(zhí)行回調(diào)函數(shù) "text",在文本中輸出hello james

setTimeout會在子線程中等待1秒,但是主線程的運(yùn)行不會受到影響!例如以下代碼:

setTimeout(()=>{     document.write("hello davis") },1000) console.log('123456');
登錄后復(fù)制

在這里會先打印出來123456(主線程),然后一秒后在文本中輸出hello davis(子線程)

回調(diào)地獄


回調(diào)地獄這個詞聽起來就非常的高大上,想要接觸Promise之前,必須要懂得什么是回調(diào)地獄,以及為什么會產(chǎn)生回調(diào)地獄?
先來看看概念:當(dāng)一個回調(diào)函數(shù)嵌套一個回調(diào)函數(shù)的時候就會出現(xiàn)一個嵌套結(jié)構(gòu)當(dāng)嵌套的多了就會出現(xiàn)回調(diào)地獄的情況
舉個例子
比如我們發(fā)送三個 ajax 請求:

  • 第一個正常發(fā)送
  • 第二個請求需要第一個請求的結(jié)果中的某一個值作為參數(shù)
  • 第三個請求需要第二個請求的結(jié)果中的某一個值作為參數(shù)

你會看到以下代碼

$.ajax({   url: '我是第一個請求',   type: 'get',   success (res) {     // 現(xiàn)在發(fā)送第二個請求     $.ajax({       url: '我是第二個請求',       type:'post',       data: { a: res.a, b: res.b },       success (res1) {         // 進(jìn)行第三個請求         $.ajax({           url: '我是第三個請求',           type:'post',           data: { a: res1.a, b: res1.b },                   success (res2) {              console.log(res2)            }         })       }     })   } })
登錄后復(fù)制

這種代碼看起來屬實(shí)是折磨人啊!當(dāng)我們把代碼寫成這樣的時候,就陷入了可維護(hù)性差的狀態(tài)了,代碼體驗(yàn)非常的不良好,看一會就給看懵了,為了解決這個問題,于是,就引入了我們的Promise,用Promise去解決回調(diào)地獄問題!

Promise


Promise異步編程的一種解決方案,比傳統(tǒng)的解決方案——回調(diào)函數(shù)和事件——更合理和更強(qiáng)大,它是一個 ECMAScript 6 提供的類,目的是更加優(yōu)雅地書寫復(fù)雜的異步任務(wù)

Promise對象有以下兩個特點(diǎn):

  • 對象的狀態(tài)不受外界影響。Promise對象代表一個異步操作,有三種狀態(tài):pending(進(jìn)行中)、fulfilled(已成功)和rejected(已失敗)。只有異步操作的結(jié)果,可以決定當(dāng)前是哪一種狀態(tài),任何其他操作都無法改變這個狀態(tài)。這也是Promise這個名字的由來,它的英語意思就是“承諾”,表示其他手段無法改變。

  • 一旦狀態(tài)改變,就不會再變,任何時候都可以得到這個結(jié)果。Promise對象的狀態(tài)改變,只有兩種可能:從pending變?yōu)閒ulfilled和從pending變?yōu)閞ejected。只要這兩種情況發(fā)生,狀態(tài)就凝固了,不會再變了,會一直保持這個結(jié)果,這時就稱為 resolved(已定型)。如果改變已經(jīng)發(fā)生了,你再對Promise對象添加回調(diào)函數(shù),也會立即得到這個結(jié)果。這與事件(Event)完全不同,事件的特點(diǎn)是,如果你錯過了它,再去監(jiān)聽,是得不到結(jié)果的。

兩個特點(diǎn)摘自于??阮一峰ES6文章

Promise語法格式

new Promise(function (resolve, reject) {   // resolve 表示成功的回調(diào)   // reject 表示失敗的回調(diào) }).then(function (res) {   // 成功的函數(shù) }).catch(function (err) {   // 失敗的函數(shù) })
登錄后復(fù)制

出現(xiàn)了new關(guān)鍵字,就明白了Promise對象其實(shí)就是一個構(gòu)造函數(shù),是用來生成Promise實(shí)例的。能看出來構(gòu)造函數(shù)接收了一個函數(shù)作為參數(shù),該函數(shù)就是Promise構(gòu)造函數(shù)的回調(diào)函數(shù),該函數(shù)中有兩個參數(shù)resolvereject,這兩個參數(shù)也分別是兩個函數(shù)!

簡單的去理解的話resolve函數(shù)的目的是將Promise對象狀態(tài)變成成功狀態(tài),在異步操作成功時調(diào)用,將異步操作的結(jié)果,作為參數(shù)傳遞出去。reject函數(shù)的目的是將Promise對象的狀態(tài)變成失敗狀態(tài),在異步操作失敗時調(diào)用,并將異步操作報出的錯誤,作為參數(shù)傳遞出去。

Promise實(shí)例生成以后,可以用then方法分別指定resolved狀態(tài)rejected狀態(tài)的回調(diào)函數(shù)。

代碼示例:

        const promise = new Promise((resolve,reject)=>{             //異步代碼             setTimeout(()=>{                 // resolve(['111','222','333'])                 reject('error')             },2000)         })         promise.then((res)=>{             //兌現(xiàn)承諾,這個函數(shù)被執(zhí)行             console.log('success',res);         }).catch((err)=>{             //拒絕承諾,這個函數(shù)就會被執(zhí)行             console.log('fail',err);         })
登錄后復(fù)制

代碼分析:

上邊說到Promise是一個構(gòu)造函數(shù),new之后等于說調(diào)用了構(gòu)造函數(shù),構(gòu)造函數(shù)中傳的參數(shù)是一個函數(shù),這個函數(shù)內(nèi)的兩個參數(shù)分別又是兩個函數(shù)(reslovereject),雖然感覺很繞,但是理清思路會很清晰的!


我們得到對象promise,promise對象中自帶有兩個方法thencatch,這兩個方法中會分別再傳入一個回調(diào)函數(shù),這個回調(diào)函數(shù)的目的在于返回你所需要成功或失敗的信息!那么怎么去調(diào)用這兩個回調(diào)函數(shù)呢?
看下方圖可以快速理解:

一文帶你輕松掌握Promise
這兩個函數(shù)分別做為參數(shù)(reslovereject)傳到上方的函數(shù)中去了.隨后在構(gòu)造函數(shù)的回調(diào)函數(shù)中寫入異步代碼(例如:ajax定時器),這里使用了定時器作為例子,如果你想表達(dá)的是成功回調(diào),你可以在內(nèi)部調(diào)用函數(shù)reslove('一般情況下是后端返回的成功數(shù)據(jù))。如果你想表達(dá)的是失敗回調(diào),你可以調(diào)用reject('一般情況下是后端返回的失敗信息').

這些就是Promise執(zhí)行的過程!雖然理解著很繞,但是多讀幾遍絕對有不一樣的收獲!

Promise鏈?zhǔn)?/span>

then方法返回的是一個新的Promise實(shí)例注意:不是原來那個Promise實(shí)例)。因此可以采用鏈?zhǔn)綄懛?/code>,即then方法后面再調(diào)用另一個then方法

實(shí)際案例:
我想要實(shí)現(xiàn)在一個數(shù)組中查看一個帖子,但是我最終的目的是得到這個帖子下面的所有評論,這該怎么實(shí)現(xiàn)呢?

實(shí)現(xiàn)思路
先從一個接口中獲取這個帖子的信息,然后通過該帖子的帖子id從而獲取到該帖子下的所有評論

代碼如下:

pajax({     url:"http://localhost:3000/news",     data : {         author : "james"     } }).then(res=>{     return pajax({         url : "http://localhost:3000/comments",         data : {             newsId : res[0].id         }     }) }).then(res=>{     console.log(res); }).catch(err=>{     console.log(err); })
登錄后復(fù)制

代碼分析:

這里使用了一個Promise已經(jīng)封裝過的ajax,我們從第一個接口中得到了帖子id,然后在then中的函數(shù)發(fā)送第二個請求(攜帶了第一個請求返回過來的參數(shù)),我們最后想要拿到第二個接口的結(jié)果,于是又有了一個then方法,但是在第一個then方法中要把一個新的Promise實(shí)例return出去,這樣的話,第二個then才起作用!(這是因?yàn)?code>then方法是Promise 實(shí)例所具有的方法,也就是說,then方法是定義在原型對象Promise.prototype上的)====>我們可以打印一下:console.log(Promise.prototype)

一文帶你輕松掌握Promise
可以看的出來原型對象Promise.prototype中是有then方法的!

Promise.all()

Promise.all()方法用于將多個 Promise 實(shí)例,包裝成一個新的 Promise 實(shí)例

語法格式:

const p = Promise.all([p1, p2, p3]);
登錄后復(fù)制

Promise.all()方法接受一個數(shù)組作為參數(shù),p1、p2、p3都是 Promise 實(shí)例,如果不是,就會調(diào)用Promise.reslove() [該方法可自行了解]自動將參數(shù)轉(zhuǎn)為 Promise 實(shí)例,再進(jìn)一步處理。

說那么多白話沒用,我們可以根據(jù)一個案例,就可以明白Promise.all()的用途了。

實(shí)際案例:
如果你想實(shí)現(xiàn)一個效果:在一個頁面中,等到頁面中所有的請求返回數(shù)據(jù)后,再渲染頁面,該怎么實(shí)現(xiàn)呢?(在實(shí)際開發(fā)中我們會看到loading加載頁面,等數(shù)據(jù)返回完后,loading加載頁面會消失,整個頁面就展現(xiàn)出來了,增強(qiáng)用戶的體驗(yàn)。)

實(shí)現(xiàn)思路:
通過Promise.all()方法,等多個接口全部接收到數(shù)據(jù)后,再統(tǒng)一進(jìn)行處理,然后渲染頁面

代碼如下:

console.log("顯示加載中") const q1 = pajax({     url:"http://localhost:3000/looplist" })  const q2 = pajax({     url:"http://localhost:3000/datalist" }) Promise.all([q1,q2]).then(res=>{     console.log(res)     console.log("隱藏加載中...") }).catch(err=>{     console.log(err) })
登錄后復(fù)制

代碼分析:

在上方代碼中,全局打印顯示加載中是代替loading的頁面,表示該頁面現(xiàn)在正是loading頁面中,等到q1q2所請求接口都得到返回的信息后,在then方法中接收收據(jù),并且可以進(jìn)行渲染頁面,同時隱藏了loading加載頁面!

小結(jié)

不論是在前端的項(xiàng)目開發(fā)中還是在前端的面試過程中,Promise的地位就是舉足輕重的,雖然解決異步編程的終極解決方案是async和await,但是它們也是基于Promise封裝而來的,在以往文章中,我就說過,學(xué)習(xí)編程重要的是搞懂某個技術(shù)是怎么實(shí)現(xiàn)的,而不是做一個cv俠,多去思考,才能進(jìn)步。繼續(xù)加油吧,少年!

贊(0)
分享到: 更多 (0)
?
網(wǎng)站地圖   滬ICP備18035694號-2    滬公網(wǎng)安備31011702889846號
99久久精品国产一区二区蜜芽| CSGO高清大片视频| AAA欧美色吧激情视频| ZEESEA在日本| 成熟交BGMBGMBGM| 国产成人丝袜视频在线观看 | FUCK东北老熟女人HD叫床| 成人午夜亚洲精品无码区| 国产精品无码AV在线播放 | 亚洲欧美日韩愉拍自拍| 中国老女人老熟女人BB操| YY8男人的天堂| 国产精品电影久久久久电影网 | 欧美亚洲另类 丝袜综合网| 色欲欲WWW成人网站| 亚洲AV成人一区二区三区在线播 | 产精品无码久久_亚洲国产精| 国产精品乱码一区二区三区| 久久国产免费直播| 欧美劲爆精品白浆视频网站| 丝袜 亚洲 另类 欧美 变态| 亚洲成A人片无码不卡| 中文字幕爆乳JULIA女教师| 成人免费毛片内射美女-百度| 国产手机AV片在线无码观你| 久久久久亚洲精品无码网址蜜桃| 欧洲美熟女乱又伦AV曰曰| 婷婷久久综合九色综合97| 亚洲无人区一码二码三码区别大吗| 99无人区码一码二码三码...| 国产成人AV一区二区三区| 精品无人区一线二线三线区别| 欧美猛少妇色XXXXⅩ| 无码熟妇人妻AV在线影片| 一本到高清视频在线观看丶| 成人性生交大片免费看中文| 精品高潮呻吟99AV无码视频| 欧洲做爰XXXⅩ富婆视频| 西西人体444WWW高清大但| 征服好友的保守人妻| 丰满熟妇岳AV无码区HD| 久久精品夜色国产亚洲AV| 日韩精品无码AV成人观看| 亚洲女人天堂成人AV在线| 被男狂揉吃奶胸60分钟视频| 精品久久久无码人妻中文字幕| 亲子乱AⅤ一区二区三区| 亚洲AV无码专区色爱天堂老鸭 | 欧洲FREEXXXX性少妇播放| 亚洲AV日韩AⅤ无码| FREE性丰满HD性欧美| 黑人巨根在线观看| 人妻av一区二区三区精品| 亚洲精品无码AⅤ片影音先锋在线| Y1111111少妇影院| 精品国产一区二区三区AV性色| 日本高清乱理伦片中文字幕| 亚洲熟妇XXXXX色黄妇| 丰满人妻熟妇乱又伦精品视频三 | 久久99青青精品免费观看| 色妓AV人妻一区二区三区| 一二三四免费观看高清在线| 国产成人无码AV片在线观看不卡| 男男GV在线观看| 亚洲Av无码成人黄网站在线| А√天堂中文官网在线地址| 久久99精品久久久久久噜噜| 熟妇内射在线二区| 91人人妻人人澡人人爽人人精品| 国产综合18久久久久久| 日韩欧美群交P片內射中文| 与大屁股熟女啪啪喷水| 国产色综合天天综合网| 日韩AV午夜在线观看| 在线播放无码高潮的视频| 国产特级毛片AAAAAA毛片| 日本水蜜桃身体乳的美白效果| 一区二区三区AV在线| 国产午夜福利内射青草| 日韩AV无码成人精品国产| √8天堂资源地址中文在线| 精品久久久久久无码人妻| 婷婷俺也去俺也去官网| A级精品国产片在线观看| 久久久久久国产精品免费无码 | 大乳VIDEOS巨大吃奶| 妺妺窝人体色WWW看美女图片| 亚洲激情无码一区| 国产精品视频免费播放| 日小骚B少妇真舒服| ASS中国人体欣赏PICS| 久久久久亚洲AV无码专区首| 亚洲AV无码乱码麻豆精品国产 | 久久久噜噜噜久噜久久| 小SAO货边洗澡边CAO你动漫| 丰满少妇张开双腿无码AV| 人妻少妇精品中文字幕av蜜桃 | 亚洲乱码中文字幕久久孕妇黑人| 国产乱子伦农村XXXX| 色哟哟网站在线观看| ZLJZLJZLJZLJ亚洲| 男女啪啪进出阳道猛进 | 亚洲AV成人午夜电影在线观看| 高清欧美性猛交XXXX黑人猛交| 秋霞午夜无码鲁丝片午夜| 中国A级毛片免费| 久久久久久久人妻无码中文字幕爆 | 亚洲AV成人网人人蜜臀| 国产精品久久久久精品三级APP| 日韩高清免费A级毛片| AV永久天堂一区二区三区| 男人边做边吃奶头视频| 中文无码日韩欧免费视频| 久久人人爽人人人人爽AV| 亚洲欧美成人综合久久久| 狠狠躁夜夜躁人人爽天天不卡软件 | 男吃奶玩乳尖高潮视频午夜| 中文字幕人妻成人综合永久| 老熟妇一区二区三区啪啪| 夜夜躁天天躁很很躁| 久久久无码精品亚洲日韩蜜臀浪潮 | 亚洲AV日韩综合一区久热| 国产未成女一区二区| 驯服小挗子2韩语中字| 国产特级毛片AAAAAA高清| 亚洲AⅤ精品无码一区二区PRO | 女教师娇喘潮喷抽搐在线视频| 中文字幕乱妇无码AV在线| 免费看国产成年无码AV片| 最新中文字幕AV无码不卡| 男女性杂交内射妇女BBWXZ| 337P日本欧洲亚洲大胆色噜噜| 男人扒开女人内裤强吻桶进去 | 岳女二人名器共侍一夫的出处| 领导在办公室含我奶头口述| 中文字幕人妻高清乱码| 欧美电影在线观看| 99精产国品一二三产| 欧美一区二区三区啪啪| 爆乳熟妇一区二区三区霸乳| 色777狠狠狠综合| 国产AⅤ无码久久丝袜美腿| 为什么放进去女的就老实了| 国产女人被狂躁到高潮小说| 亚洲VA欧美VA天堂V国产综合| 精品亚洲AⅤ无码一区二区三区| 亚洲一区二区三区无码久久| 领导边摸边吃奶边做爽在线观看| 51成品网站W灬源码1688| 全部免费特黄特色大片| 多毛丰满日本熟妇| 午夜不卡久久精品无码免费| 娇妻被黑人杂交呻吟| 一二三四在线视频社区8| 女人高潮抽搐30分钟| 成人欧美一区二区三区黑人牛| 熟妇啊轻点灬大JI巴太粗| 国产欧洲野花A级| 亚洲人成未满十八禁网站| 免费女人18毛片A级毛片视频| XXXXHDTEEN欧美内射| 四虎影视1304T| 护士扒下内裤让我爽一夜| 亚洲综合无码AV一区二区| 欧美丰满少妇人妻精品| 粉嫩小泬流出白浆| 亚洲AV无码专区在线观看漫画| 旧番无码熟肉动漫在线观看| wwwxxx一区二区| 锕锕锕锕锕锕锕锕好疼动免费| 性无码免费一区二区三区在线| 国产成人精品一区二三区| 亚洲精品乱码久久久久久| 美女高潮无套内谢| 不收费的十大免费好用的软件| 无码中文亚洲AV影音先锋无码 | 国产白浆喷水在线视频| 亚洲国产精品美女久久久久| 免费无遮挡色视频网站| 国产A在亚洲线播放| 亚洲日韩中文字幕无码专区| 欧美自拍亚洲综合在线| 国产欧美精品一区二区色综合| 野花日本免费完整版高清版8| 青青草无码精品伊人久久7| 国产精品免费AⅤ片在线观看| 亚洲最大AV无码网站| 日本高清在线视频WWW色| 国产日产欧产精品精品软件| 永久免费看啪啪的网站| 色婷婷亚洲精品综合影院| 精品国产成人A区在线观看| 9L国产精品久久久久尤物| 无码人妻丰满熟妇区毛片| 看黄A大片爽爽影院免费无码| 纯肉无遮挡H肉动漫在线观看国产| 亚洲国产成人久久综合人| 人妻丰满熟妇AV无码区| 娇妻系列交换27部多P小| 北条麻妃一区二区三区AV高清 |