日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

第十八节:教你如何使用ES6的Promise对象

發布時間:2025/3/15 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 第十八节:教你如何使用ES6的Promise对象 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

????????Promise對象,ES6新增的一個全新特性,今天我們要好好學習一下它。

Promise的設計初衷

????????

????????首先,我們先一起了解一下,為什么要設計出這么一個玩意兒,用它是為了解決什么問題?

????????帶著這個問題,我們來回想一下日常開發中,經常需要用到ajax請求數據,拿到數據后,再進行一些處理。

????????可有一次,你需要用ajax進行多次請求,而且,每次請求都依賴上一次請求返回的數據來作為參數,然后繼續發出請求,你把代碼寫成了這樣:


? ?//------請求A 開始---------
? ?$.ajax({
?? ? ?? success:function(res1){


???? ? ???? //------請求B 開始----
????? ? ??? $.ajax({
??????????? ? ? success:function(res2){


???????????? ? ???? //----請求C 開始---
????????????? ? ??? $.ajax({
??????????????? ? ????? success:function(res3){
????????????? ? ? ??????}
???????????? ? ???? });
??????????????? ? ??? //---請求C 結束---


?????????? ? ?? } ? ?
??????? ? ? });
??????? ? ? //------請求B 結束-----


??? ? ? }
? ?});
? ?//------請求A 結束---------

?

????????上面的案例,假設請求C需要依賴請求B返回的數據,所以,C只能放在B的success函數內;B需要依賴A請求得到的數據作為參數,所以,B只能放在A的success函數內;也就是:請求A包含著請求B,請求B又包含了請求C。

????????就這樣,請求順序為:請求A -> 請求B -> 請求C,最后你也能順利的完成了任務。

傳統寫法的不足

????????

????????但是這樣寫,會有一些缺點:

1. ?如果存在多個請求操作層層依賴的話,那么以上的嵌套就有可能不止三層那么少了,加上每一層還會有復雜的業務邏輯處理,代碼可讀性也越來越差,不直觀,調試起來也不方便。如果多人開發的時候沒有足夠的溝通協商,大家的代碼風格不一致的話,更是雪上加霜,給后面的維護帶來極大的不便。

2. ?如果請求C的需要依賴A和B的結果,但是請求A和B缺互相獨立,沒有依賴關系,以上的實現方式,就使得B必須得到A請求完成后才可以執行,無疑是消耗了更多的等待時間

????????既然使用這種回調函數層層嵌套(又稱:回調地獄)的形式存在缺點,ES6想了辦法治它,所以就有了Promise的出現了。

????????那么我們就知道了:Promise對象能使我們更合理、更規范地進行處理異步操作

Promise的基本用法?

????????

????????接下來,我們就看看它的基本用法:


? ?let pro = new Promise(function(resolve,reject){
? ? ??? //....
? ?});
? ?

????????Promise對象是全局對象,你也可以理解為一個類,創建Promise實例的時候,要有那個new關鍵字。參數是一個匿名函數,其中有兩個參數:resolve和reject,兩個函數均為方法。resolve方法用于處理異步操作成功后業務;reject方法用于操作異步操作失敗后的業務。

Promise的是三種狀態

????????

Promise對象有三種狀態:

  • pending:剛剛創建一個Promise實例的時候,表示初始狀態;

  • fulfilled:resolve方法調用的時候,表示操作成功;

  • rejected:reject方法調用的時候,表示操作失敗;

  • ????????狀態只能從 初始化 -> 成功 ?或者 ?初始化 -> 失敗,不能逆向轉換,也不能在成功fulfilled 和失敗rejected之間轉換


    ? ?let pro = new Promise(function(resolve,reject){
    ??? ? ? //實例化后狀態:pending

    ??? ? ? if('操作成功'){
    ??????? ? ? resolve();
    ??????? ? ? //resolve方法調用,狀態為:fulfilled
    ??? ? ? }else{
    ??????? ? ? reject();
    ??????? ? ? //reject方法調用,狀態為:rejected
    ??? ? ? }
    ? ?});
    ? ?

    ????????上面的注釋,講清楚了一個Promise實例的狀態改變情況。

    ????????初始化實例后,對象的狀態就變成了pending;當resolve方法被調用的時候,狀態就變成了:成功fulfilled;當reject方法被調用的時候,狀態就會有pending變成失敗rejected。

    ?

    then( )方法

    ????????了解了Promise的創建和狀態,我們來學習一個最重要的實例方法:then( )方法。

    ????????then( )方法:用于綁定處理操作后的處理程序。

    ? ?
    ? ?pro.then(function (res) {
    ??? ? ? //操作成功的處理程序
    ? ?},function (error) {
    ??? ? ? //操作失敗的處理程序
    ? ?});
    ? ?

    ????????參數是兩個函數,第一個用于處理操作成功后的業務,第二個用于處理操作異常后的業務

    catch( )方法?

    ????????

    ????????對于操作異常的程序,Promise專門提供了一個實例方法來處理:catch( )方法。


    ? ?pro.catch(function (error) {
    ??? ? ? //操作失敗的處理程序
    ? ?});
    ? ?

    ????????

    ????????catch只接受一個參數,用于處理操作異常后的業務。

    ????????綜合上面的兩個方法,大家都建議將then方法用于處理操作成功,catch方法用于處理操作異常,也就是:


    ? ?pro.then(function (res) {
    ??? ? ? //操作成功的處理程序
    ? ?}).catch(function (error) {
    ??? ? ? //操作失敗的處理程序
    ? ?});
    ? ?

    ????????之所以能夠使用鏈式調用,是因為then方法和catch方法調用后,都會返回promise對象

    ?

    ????????講了那么多,如果你之前一點都沒接觸過Promise的話,現在一定很懵逼,沒關系,下面我們用一個案例來串聯前面的知識點,演示一下,認真閱讀注釋:


    ? ?//用new關鍵字創建一個Promise實例
    ? ?let pro = new Promise(function(resolve,reject){
    ??? ? ? //假設condition的值為true
    ??? ? ? let condition = true;

    ??? ? ? if(condition){
    ????? ? ??? //調用操作成功方法
    ? ? ? ? ? ?resolve('操作成功');
    ?????? ? ?? //狀態:pending->fulfilled
    ?? ? ?? }else{
    ??????? ? ? //調用操作異常方法
    ? ? ? ? ? ?reject('操作異常');
    ?????? ? ?? //狀態:pending->rejected
    ??? ? ? }
    ? ?});

    ? ?//用then處理操作成功,catch處理操作異常
    ? ?pro.then(function (res) {

    ??? ? ? //操作成功的處理程序
    ? ? ? ?console.log(res)

    ? ?}).catch(function (error) {

    ??? ? ? //操作失敗的處理程序
    ? ? ? ?console.log(error)

    ? ?});
    ? ?//控制臺輸出:操作成功

    ????????上面案例的注釋十分詳細,串聯起了上面介紹的所有知識點:創建實例,狀態轉換,then方法和catch方法的使用。

    ????????由于我們設置了變量condition的值為true,所以執行后控制臺輸出的結果是:“操作成功”。

    ?

    ????????上面就是Promise用于處理操作異常的這個過程;但是,正如文章開頭講到的,如果多個操作之間層層依賴,我們用Promise又是怎么處理的呢?

    完整案例

    ????????

    ????????我們看看下面的案例,代碼有點長,但是一點都不復雜:


    ? ?let pro = new Promise(function(resolve,reject){

    ??? ? ? if(true){
    ??????? ? ? //調用操作成功方法
    ? ? ? ? ? ?resolve('操作成功');
    ?? ? ?? }else{
    ? ? ? ? ? ?//調用操作異常方法
    ? ? ? ? ? ?reject('操作異常');
    ?? ? ?? }
    ? ?});

    ? ?//用then處理操作成功,catch處理操作異常
    ? ?pro.then(requestA)
    ??? ? ? .then(requestB)
    ??? ? ? .then(requestC)
    ??? ? ? .catch(requestError);

    ? ?function requestA(){
    ??? ? ? console.log('請求A成功');
    ??? ? ? return '請求B,下一個就是你了';
    ? ?}
    ? ?function requestB(res){
    ??? ? ? console.log('上一步的結果:'+res);
    ??? ? ? console.log('請求B成功');
    ??? ? ? return '請求C,下一個就是你了';
    ? ?}
    ? ?function requestC(res){
    ??? ? ? console.log('上一步的結果:'+res);
    ??? ? ? console.log('請求C成功');
    ? ?}
    ? ?function requestError(){
    ??? ? ? console.log('請求失敗');
    ? ?}

    ? ?//打印結果:
    ? ?//請求A成功
    ? ?//上一步的結果:請求B,下一個就是你了
    ? ?//請求B成功
    ? ?//上一步的結果:請求C,下一個就是你了
    ? ?//請求C成功

    ?

    ????????案例中,先是創建一個實例,還聲明了4個函數,其中三個是分別代表著請求A,請求B,請求C;有了then方法,三個請求操作再也不用層層嵌套了。我們使用then方法,按照調用順序,很直觀地完成了三個操作的綁定,并且,如果請求B依賴于請求A的結果,那么,可以在請求A的程序用使用return語句把需要的數據作為參數,傳遞給下一個請求,案例中我們就是使用return實現傳遞參數給下一步操作的。

    更直觀的圖解

    ????????如果你還是是懂非懂,沒關系,前端君拼了,上圖:


    ????????圖有點粗糙,但是能反應出上面程序的執行過程,幫助大家加深理解。

    ?

    ????????除了提供了實例方法以外,Promise還提供了一些類方法,也就是不用創建實例,也可以調用的方法。

    ????????下面,我們來學習幾個重要的。

    ?Promise.all( )方法

    ????????Promise.all( )方法:接受一個數組作為參數,數組的元素是Promise實例對象,當參數中的實例對象的狀態都為fulfilled時,Promise.all( )才會有返回

    ????????我們來演示一下:


    ? ?//創建實例pro1
    ? ?let pro1 = new Promise(function(resolve){
    ??? ? ? setTimeout(function () {
    ??????? ? ? resolve('實例1操作成功');
    ??? ? ? },5000);
    ? ?});
    ? ?
    ? ?//創建實例pro2
    ? ?let pro2 = new Promise(function(resolve){
    ??? ? ? setTimeout(function () {
    ??????? ? ? resolve('實例2操作成功');
    ??? ? ? },1000);
    ? ?});

    ? ?
    ? ?Promise.all([pro1,pro2]).then(function(result){
    ??? ? ? console.log(result);
    ? ?});
    ? ?//打印結果:["實例1操作成功", "實例2操作成功"]

    ????????上述案例,我們創建了兩個Promise實例:pro1和pro2,我們注意兩個setTimeout的第二個參數,分別是5000毫秒和1000毫秒,當我們調用Promise.all( )方法的時候,會延遲到5秒才控制臺會輸出結果。

    ????????因為1000毫秒以后,實例pro2進入了成功fulfilled狀態;此時,Promise.all( )還不會有所行動,因為實例pro1還沒有進入成功fulfilled狀態;等到了5000毫秒以后,實例pro1也進入了成功fulfilled狀態,Promise.all( )才會進入then方法,然后在控制臺輸出:["實例1操作成功","實例2操作成功"]。

    ????????這個方法有什么用呢?一般這樣的場景:我們執行某個操作,這個操作需要得到需要多個接口請求回來的數據來支持,但是這些接口請求之前互不依賴,不需要層層嵌套。這種情況下就適合使用Promise.all( )方法,因為它會得到所有接口都請求成功了,才會進行操作。

    ?

    ?Promise.race( )方法

    ????????

    ????????另一個類似的方法是Promise.race()方法:它的參數要求跟Promise.all( )方法一樣,不同的是,它參數中的promise實例,只要有一個狀態發生變化(不管是成功fulfilled還是異常rejected),它就會有返回,其他實例中再發生變化,它也不管了。


    ? ?//初始化實例pro1
    ? ?let pro1 = new Promise(function(resolve){
    ??? ? ? setTimeout(function () {
    ??????? ? ? resolve('實例1操作成功');
    ??? ? ? },4000);
    ? ?});

    ? ?//初始化實例pro2
    ? ?let pro2 = new Promise(function(resolve,reject){
    ??? ? ? setTimeout(function () {
    ??????? ? ? reject('實例2操作失敗');
    ??? ? ? },2000);
    ? ?});

    ? ?Promise.race([pro2,pro1]).then(function(result){
    ??? ? ? console.log(result);
    ? ?}).catch(function(error){
    ??? ? ? console.log(error);
    ? ?});
    ? ?//打印結果:實例2操作失敗

    ????????同樣是兩個實例,實例pro1不變,不同的是實例pro2,這次我們調用的是失敗函數reject。

    ????????由于pro2實例中2000毫秒之后就執行reject方法,早于實例pro1的4000毫秒,所以最后輸出的是:實例2操作失敗。

    ????????以上就是對Promise對象的內容講解,上面提到了一個概念:回調地獄;指的是過多地使用回調函數嵌套,使得調試和維護起來極其的不便。

    ????????下面給大家看個真正的回調地獄,前方高能,圖慎點:


    ?

    本節小結

    ?

    總結:Promise是一個讓開發者更合理、更規范地用于處理異步操作的對象,它有三種狀態:初始化、操作成功、操作異常。使用實例方法:then( ) 和 ?catch( ) 來綁定處理程序;還提供了類方法:Promise.all( ) 和 Promise.race( )。

    總結

    以上是生活随笔為你收集整理的第十八节:教你如何使用ES6的Promise对象的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 国产美女诱惑 | 成年人免费看黄色 | 粗喘呻吟撞击猛烈疯狂 | 国产裸体美女永久免费无遮挡 | 午夜精品久久久久久久久久蜜桃 | 亚洲色图.com | 国产精品99视频 | av最新网| 极品丰满少妇 | 国产精品极品白嫩 | 婷婷在线观看视频 | 99性视频 | 91丝袜| 久久久久久亚洲中文字幕无码 | 日本日韩欧美 | www.国产成人 | 91久久国产综合久久91精品网站 | 欧美精品第二页 | 中文字幕无码人妻少妇免费 | 国产精品视频导航 | 色综合激情网 | 深夜福利免费视频 | a视频免费在线观看 | 亚洲欧美系列 | 一级特级片 | 亚洲字幕av一区二区三区四区 | www.亚洲黄色| 性猛交xxxx乱大交孕妇2十 | 亚洲一区在线视频观看 | 欧美黄网站在线观看 | 日韩精品一区二区三区在线观看 | 天海翼一二三区 | 国产精品美女久久久久av爽 | 国产天天骚| 欧美专区在线播放 | 天天射影院 | 国产污片在线观看 | 国内自拍第三页 | 蜜桃成熟时李丽珍在线观看 | 欧洲av网站| 欧美特级黄色录像 | 热久久影院 | 人妻激情偷乱频一区二区三区 | 亚洲第二页 | 日韩二三区 | 台湾av在线 | 奇米在线视频 | 中文字幕.com | 大肉大捧一进一出好爽 | 夜夜嗨av色一区二区不卡 | 欧美全黄| caoprom超碰 | av在线一 | 极品色综合 | 男人和女人日b视频 | 国产三级不卡 | 青草av在线 | 国产一区二区三区毛片 | 国产毛片一区二区三区 | 欧美熟妇另类久久久久久不卡 | 老湿机69福利 | 欧美大片在线免费观看 | 91污网站 | 中文字幕永久在线播放 | 欧美a级在线 | 很黄的网站在线观看 | 星空大象在线观看免费播放 | 在线视频一区二区三区 | 亚洲少妇中文字幕 | 欧美黑人性生活 | 国语精品久久 | 国产一区二区在线视频 | 国产精品欧美精品 | 国产精品wwww | 夜色一区 | 放荡闺蜜高h季红豆h | 一级α片免费看刺激高潮视频 | 伊人爱爱网| 91精品久久久久久久久久 | 国产精选一区二区三区 | 美国少妇性做爰 | 超级黄色录像 | 久久在线免费观看视频 | 国产日皮视频 | 日韩在线免费av | 日韩经典一区二区 | 九草视频在线 | 六月天婷婷 | xxxxhd欧美| 色哟哟欧美精品 | 国产精品xxxx喷水欧美 | 日本美女日批视频 | 91社区视频 | 日韩亚洲一区二区 | 河北彩花av在线播放 | 爱爱免费网站 | 蜜色视频 | 在线精品一区二区 | 高清一二三区 |