首頁 web前端 js教程 前端 Promise 常見的一些應用場景

前端 Promise 常見的一些應用場景

Jun 15, 2020 am 10:08 AM
promise

這篇將結合自身使用ES6 Promise的情況,總結下Promise在我們專案開發中的常見的應用場景,當然,Promise 也許不是唯一選項,但是我們作為一個合格的前端開發人員,我們有必要了解它。

Promise.all


#語法:Promise.all(iterable)

參數:一個可迭代對象,如Array。

傳回值:

  • 如果傳遞的iterable為空,則是已經解決的Promise。

Promise.all([]).then(res=>{
    console.log(res)//[]
})
登入後複製
  • 非異步解析的Promise(如果傳遞的Iterable不包含Promise)。請注意,在這種情況下,Google Chrome 58返回已解決的承諾。

Promise.all([1,2,3]).then(res=>{
    console.log(res)//[1,2,3]
})
登入後複製
  • 當給定可迭代物件中的所有promise已解決,或任何promise均被拒絕時,此傳回的promise將被非同步解析/拒絕(堆疊為空白時)

     1. 當給定可迭代物件中的所有promise 已解決

let promise1 = new Promise((resolve,reject)=>{
    resolve(1)
})
let promise2 = new Promise((resolve,reject)=>{
    resolve(2)
})

Promise.all([promise1,promise2,3]).then(res=>{
    console.log(res)//[1,2,3]
})
登入後複製

           2..當給予可迭代物件中的任何promise被拒絕時

let promise1 = new Promise((resolve,reject)=>{
    resolve(1)
})
let promise2 = new Promise((resolve,reject)=>{
    reject(2)
})

Promise.all([promise1,promise2,3]).then(res=>{
    console.log(res)
}).catch(err=>{
    console.log(err)//2
})
登入後複製

描述:

此方法對於匯總多個promise的結果很有用, 在ES6中可以將多個Promise.all非同步請求並行操作:

1.當所有結果成功返回時按照請求順序返回成功;

2.當其中有一個失敗方法時,則進入失敗方法;

##應用場景1 :多個請求結果合併在一起

具體描述:一個頁面,有多個請求,我們需求所有的請求都返回資料後再一起處理渲染

#思考:如果並發請求的話,每個請求的loading狀態要單獨設置,多個的話可能多個loading 重合,頁面顯示的內容根據請求返回數據的快慢有所差異,具體表現在渲染的過程,為提升使用者體驗,我們可以採用所有請求返回資料後,再一起渲染,此時我們關閉請求的單獨loading設置,透過Promise.all 匯總請求結果,從開始到結束,我們只設置一個loading 即可。


//1.获取轮播数据列表
function getBannerList(){
    return new Promise((resolve,reject)=>{
        setTimeout(function(){
            resolve('轮播数据')
        },300)
    })
}

//2.获取店铺列表
function getStoreList(){
   return new Promise((resolve,reject)=>{
        setTimeout(function(){
            resolve('店铺数据')
        },500)
    })
}

//3.获取分类列表
function getCategoryList(){
   return new Promise((resolve,reject)=>{
        setTimeout(function(){
            resolve('分类数据')
        },700)
    })
}

function initLoad(){
    // loading.show() //加载loading
    Promise.all([getBannerList(),getStoreList(),getCategoryList()]).then(res=>{
        console.log(res)
        // loading.hide() //关闭loading
    }).catch(err=>{
        console.log(err)
        // loading.hide()//关闭loading
    })
}
//数据初始化    
initLoad()
登入後複製

應用程式場景2:合併請求結果並處理錯誤

描述:我們需求單獨處理一個請求的資料渲染和錯誤處理邏輯,有多個請求,我們就需要在多個地方寫

思考:我們能否把多個請求合併在一起,哪怕有的請求失敗了,也返回給我們,我們只需要在一個地方處理這些數據和錯誤的邏輯即可。

//1.获取轮播图数据列表
function getBannerList(){
    return new Promise((resolve,reject)=>{
        setTimeout(function(){
            // resolve('轮播图数据')
            reject('获取轮播图数据失败啦')
        },300)
    })
}

//2.获取店铺列表
function getStoreList(){
   return new Promise((resolve,reject)=>{
        setTimeout(function(){
            resolve('店铺数据')
        },500)
    })
}

//3.获取分类列表
function getCategoryList(){
    return new Promise((resolve,reject)=>{
        setTimeout(function(){
            resolve('分类数据')
        },700)
    })
}

function initLoad(){
    // loading.show()
    Promise.all([
        getBannerList().catch(err=>err),
        getStoreList().catch(err=>err),
        getCategoryList().catch(err=>err)
    ]).then(res=>{
        console.log(res) // ["获取轮播图数据失败啦", "店铺数据", "分类数据"]
        
        if(res[0] == '轮播图数据'){
            //渲染
        }else{
            //获取 轮播图数据 失败的逻辑
        }
        if(res[1] == '店铺数据'){
            //渲染
        }else{
            //获取 店铺列表数据 失败的逻辑
        }
        if(res[2] == '分类数据'){
            //渲染
        }else{
             //获取 分类列表数据 失败的逻辑
        }
        
        // loading.hide()
    })
}

initLoad()
登入後複製

有時候頁面掛掉了,可能因為介面異常導致,或許只是一個無關緊要的介面掛掉了。那麼一個介面掛掉了為什麼會導致整個頁面無資料呢? Promise.all告訴我們,如果參數中promise 有一個失敗(rejected),此實例回呼失敗(reject),就不再執行then方法回調,以上用例正好可以解決此種問題

應用場景3:驗證多個請求結果是否都是滿足條件

描述:在一個微信小程式專案中,做一個表單的輸入內容安全驗證,呼叫的是雲函數寫的方法,表單有多7個欄位需要驗證,都是呼叫的一個內容安全校驗接口,全部驗證通過則可以進行正常的提交

function verify1(content){
    return new Promise((resolve,reject)=>{
        setTimeout(function(){
            resolve(true)
        },200)
    })
}

function verify2(content){
    return new Promise((resolve,reject)=>{
        setTimeout(function(){
            resolve(true)
        },700)
    })
}

function verify3(content){
    return new Promise((resolve,reject)=>{
        setTimeout(function(){
            resolve(true)
        },300)
    })
}



Promise.all([verify1('校验字段1的内容'),verify2('校验字段2的内容'),verify3('校验字段3的内容')]).then(result=>{
    console.log(result)//[true, true, true]

    let verifyResult = result.every(item=>item)
    //验证结果
    console.log(verifyResult?'通过验证':'未通过验证')// 通过验证
}).catch(err=>{
    console.log(err)
})
登入後複製

Promise .race


語法:Promise.race(iterable)

參數: iterable 可迭代的對象,例如Array 。可迭代的。

傳回值:Promise.race(iterable) 方法傳回一個promise,一旦迭代器中的某個promise解決或拒絕,傳回的promise就會解決或拒絕

描述race 函數傳回一個Promise,它將與第一個傳遞的promise 相同的完成方式完成。它可以是完成( resolves),也可以是失敗(rejects),這取決於第一個完成的方式是兩個中的哪一個。

如果傳的迭代是空的,則傳回的 promise 將永遠等待。

如果迭代包含一個或多個非承諾值和/或已解決/拒絕的承諾,則 Promise.race 將解析為迭代中找到的第一個值。

應用程式場景1:圖片請求逾時

//请求某个图片资源
function requestImg(){
    var p = new Promise(function(resolve, reject){
        var img = new Image();
        img.onload = function(){
           resolve(img);
        }
        //img.src = "https://b-gold-cdn.xitu.io/v3/static/img/logo.a7995ad.svg"; 正确的
        img.src = "https://b-gold-cdn.xitu.io/v3/static/img/logo.a7995ad.svg1";
    });
    return p;
}

//延时函数,用于给请求计时
function timeout(){
    var p = new Promise(function(resolve, reject){
        setTimeout(function(){
            reject('图片请求超时');
        }, 5000);
    });
    return p;
}

Promise
.race([requestImg(), timeout()])
.then(function(results){
    console.log(results);
})
.catch(function(reason){
    console.log(reason);
});
登入後複製

#應用程式場景2:請求逾時提示

描述:有些時候,我們前一秒刷著新聞,下一秒進入電梯後,手機頁面上就會提示你「網路不佳」

//请求
function request(){
    return new Promise(function(resolve, reject){
       setTimeout(()=>{
            resolve('请求成功')
       },4000)
    })
}

//请求超时提醒
function timeout(){
    var p = new Promise(function(resolve, reject){
        setTimeout(function(){
            reject('网络不佳');
        }, 3000);
    });
    return p;
}



Promise.race([
    request(),
    timeout()
])
.then(res=>{
    console.log(res)
}).catch(err=>{
    console.log(err)//网络不佳
})
登入後複製

Promise.prototype.then


應用程式場景1:下個請求依賴上個請求的結果#

描述:类似微信小程序的登录,首先需要 执行微信小程序的 登录 wx.login 返回了code,然后调用后端写的登录接口,传入 code ,然后返回 token ,然后每次的请求都必须携带 token,即下一次的请求依赖上一次请求返回的数据

function A(){
    return new Promise((resolve,reject)=>{
        setTimeout(()=>{
            resolve('B依赖的数据')
        },300)
    })
}
function B(prams){
    return new Promise((resolve,reject)=>{
        setTimeout(()=>{
            resolve(prams + 'C依赖的数据')
        },500)
    })
}
function C(prams){
    return new Promise((resolve,reject)=>{
        setTimeout(()=>{
            resolve(prams)
        },1000)
    })
}

//我们期望的是走 try ,由于A B C模拟的请求中都是没有reject,用 try catch 捕获错误
try{
    A().then( res=>B(res) ).then( res=>C(res) ).then( res=>{
        console.log(res)//B依赖的数据C依赖的数据
    })   
} catch(e){
    
}
登入後複製

应用场景2:中间件功能使用

描述:接口返回的数据量比较大,在一个then 里面处理 显得臃肿,多个渲染数据分别给个then,让其各司其职

//模拟后端返回的数据

let result = {
    bannerList:[
        {img:'轮播图地址'}
    //...
    ],
    storeList:[
        {name:'店铺列表'}
    //...
    ],
    categoryList:[
        {name:'分类列表'}
    //...
    ],
    //...
}

function getInfo(){
    return new Promise((resolve,reject)=>{
        setTimeout(()=>{
            resolve(result)
        },500)
    })
}

getInfo().then(res=>{

    let { bannerList } = res
    //渲染轮播图
    console.log(bannerList)
    return res
}).then(res=>{
    
    let { storeList } = res
    //渲染店铺列表
    console.log(storeList)
    return res
}).then(res=>{
    let { categoryList } = res
    console.log(categoryList)
    //渲染分类列表
    
    return res
})
登入後複製

推荐教程:《JS教程

以上是前端 Promise 常見的一些應用場景的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

言出必行:兌現承諾的好處和壞處 言出必行:兌現承諾的好處和壞處 Feb 18, 2024 pm 08:06 PM

在日常生活中,我們常常會遇到承諾與兌現之間的問題。無論是在個人關係中,或是在商業交易中,承諾的兌現都是建立信任的關鍵。然而,承諾的利與弊也常常會引起爭議。本文將探討承諾的利與弊,並給予一些建議,如何做到言出必行。承諾的利是顯而易見的。首先,承諾可以建立信任。當一個人信守承諾時,他會讓別人相信自己是個可信賴的人。信任是人與人之間建立的紐帶,它可以讓人們更加

在Vue應用中遇到Uncaught (in promise) TypeError怎麼辦? 在Vue應用中遇到Uncaught (in promise) TypeError怎麼辦? Jun 25, 2023 pm 06:39 PM

Vue是一款受歡迎的前端框架,在開發應用時經常會遇到各種各樣的錯誤和問題。其中,Uncaught(inpromise)TypeError是常見的一種錯誤型別。在本篇文章中,我們將探討它的產生原因和解決方法。什麼是Uncaught(inpromise)TypeError? Uncaught(inpromise)TypeError錯誤通常出現在

深入了解Promise.resolve() 深入了解Promise.resolve() Feb 18, 2024 pm 07:13 PM

Promise.resolve()詳解,需要具體程式碼範例Promise是JavaScript中一種用來處理非同步操作的機制。在實際開發中,常常需要處理一些需要依序執行的非同步任務,而Promise.resolve()方法就是用來傳回一個已經Fulfilled狀態的Promise物件。 Promise.resolve()是Promise類別的靜態方法,它接受一個

實例解析ES6 Promise的原理與使用 實例解析ES6 Promise的原理與使用 Aug 09, 2022 pm 03:49 PM

利用Promise對象,把普通函數改成返回Promise的形式,解決回調地獄的問題。明白Promise的成功失敗呼叫邏輯,可以靈活的進行調整。理解核心知識,先用起來,慢慢整合吸收知識。

哪些瀏覽器支援Promise? 哪些瀏覽器支援Promise? Feb 19, 2024 pm 04:41 PM

瀏覽器相容性:哪些瀏覽器能夠支援Promise?隨著Web應用程式的複雜性不斷提高,開發人員迫切需要解決JavaScript中的非同步程式設計問題。過去,開發人員通常使用回調函數來處理非同步操作,但這會導致程式碼複雜且難以維護。為了解決這個問題,ECMAScript6引入了Promise,它提供了一種更直觀、更靈活的處理非同步操作的方式。 Promise是一種用於處理異

promise物件有哪些 promise物件有哪些 Nov 01, 2023 am 10:05 AM

promise物件狀態有:1、pending:初始狀態,既不是成功,也不是失敗狀態;2、fulfilled:意味著操作成功完成;3、rejected:意味著操作失敗。一個Promise物件一旦完成,就會從pending狀態變成fulfilled或rejected狀態,且不能再改變。 Promise物件在JavaScript中被廣泛使用,以處理如AJAX請求、定時操作等非同步操作。

promise什麼意思 promise什麼意思 Nov 02, 2023 pm 05:30 PM

Promise是一種用於處理非同步操作的程式設計模式,它是一種代表了非同步操作最終完成或失敗的對象,可以看作是對非同步操作的一種承諾,它可以更好地管理和組織非同步程式碼,使得程式碼更可讀性高、可維護性強。 Promise物件有三個狀態:pending、fulfilled和rejected。 Promise的核心思想是將非同步操作從回調函數中分離出來,透過鍊式呼叫的方式來表達非同步操作之間的依賴關係。

PHP 函數回傳 Promise 物件有什麼優勢? PHP 函數回傳 Promise 物件有什麼優勢? Apr 19, 2024 pm 05:03 PM

優點:非同步和非阻塞,不阻塞主執行緒;提高程式碼可讀性和可維護性;內建錯誤處理機制。

See all articles