欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JS中Promise的使用及封裝方式

 更新時間:2023年03月06日 10:10:35   作者:半度℃溫?zé)? 
這篇文章主要介紹了JS中Promise的使用及封裝方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

Promise 是什么

  • Promise 是異步編程的一種解決方案,比傳統(tǒng)的解決方案——回調(diào)函數(shù)和事件——更合理和更強(qiáng)大。
  • 簡單說就是一個容器,里面保存著某個未來才會結(jié)束的事件(通常是一個異步操作)的結(jié)果。
  • 從語法上說,Promise 是一個對象,從它可以獲取異步操作的消息。Promise 提供統(tǒng)一的 API,各種異步操作都可以用同樣的方法進(jìn)行處理。

Promise 的特點(diǎn)

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

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

3. 將異步操作以同步操作的流程表達(dá)出來,避免了層層嵌套的回調(diào)函數(shù)(回調(diào)地獄)

Promise 的缺點(diǎn)

  • 1. 無法取消 Promise,一旦新建它就會立即執(zhí)行,無法中途取消
  • 2. 如果不設(shè)置回調(diào)函數(shù),Promise內(nèi)部拋出的錯誤,不會反應(yīng)到外部
  • 3. 當(dāng)處于pending狀態(tài)時,無法得知目前進(jìn)展到哪一個階段(剛剛開始還是即將完成)

Promise 的原理

ES6 規(guī)定,Promise 對象是一個構(gòu)造函數(shù),用來生成 Promise 實(shí)例。通過在函數(shù)內(nèi)部 return 一個 Promise 對象的實(shí)例,這樣就可以使用 Promise 的屬性和方法進(jìn)行下一步操作了。    

Promise 構(gòu)造函數(shù)接受一個函數(shù)作為參數(shù),該函數(shù)的兩個參數(shù)分別是 resolve 和 reject。它們是兩個函數(shù),由 JavaScript 引擎提供,不用自己部署

const promise = new Promise(function(resolve, reject) {
? if (/* 異步操作成功 */){
? ? resolve(value)
? } else {
? ? reject(error)
? }
})

Promise 的方法

1. Promise.prototype.then()

then()方法就是把原來的回調(diào)寫法分離出來,在異步操作執(zhí)行完后,用鏈?zhǔn)秸{(diào)用的方式執(zhí)行回調(diào)函數(shù)。

而 Promise的優(yōu)勢就在于這個鏈?zhǔn)秸{(diào)用。

我們可以在 then 方法中繼續(xù)寫 Promise 對象并返回,然后繼續(xù)調(diào)用 then 來進(jìn)行回調(diào)操作。

resolve 的用法

let promise = new Promise(function(resolve, reject) {
? console.log('Promise')
? resolve('已完成')
});

promise.then(function(data) {
? console.log('resolved.',data)
})

console.log('Hi!')

// ?Promise
// ?Hi!
// ?resolved. 123

reject 的用法

reject 方法就是把 Promise 的狀態(tài)置為已失?。≧ejected),這時 then 方法執(zhí)行“失敗”情況的回調(diào)(then 方法的第二參數(shù))

let promise = new Promise(function(resolve, reject) {
? reject('NO')
});

promise.then(function(data) {
? console.log('resolved.',data)
},function(data){
? console.log('rejected.',data)
})

// ?rejected. NO

2. Promise.prototype.catch()

如果異步操作拋出錯誤,當(dāng)前 Promise 對象狀態(tài)就會變?yōu)?rejected,就會調(diào)用 catch 方法指定的回調(diào)函數(shù),處理這個錯誤。

另外,then 方法指定的回調(diào)函數(shù),如果運(yùn)行中拋出錯誤,也會被 catch 方法捕獲。

catch 方法返回的也是一個 Promise 對象,因此后面還可以接著調(diào)用then方法。

const promise = new Promise(function(resolve, reject) {
? resolve('OK')
})

promise.then(function(data) {
? console.log(data)
? console.log(num)
}).catch(function(err) {
? console.log(err)
})

// OK
// ReferenceError: num is not defined

3. Promise.prototype.finally()

finally 方法用于指定不管 Promise 對象最后狀態(tài)如何,在執(zhí)行完 then 或 catch 指定的回調(diào)函數(shù)以后,都會執(zhí)行 finally 方法指定的回調(diào)函數(shù)。

finally 方法的回調(diào)函數(shù)不接受任何參數(shù),在 finally 方法里面的操作,與狀態(tài)無關(guān),不依賴于 Promise 的執(zhí)行結(jié)果。

// 服務(wù)器使用 Promise 處理請求,然后使用 finally 方法關(guān)掉服務(wù)器
server.listen(port)
? .then(function () {
? ? // ...
? })
? .finally(server.stop)

4. Promise.all()

Promise 的 all 方法(傳入一個數(shù)組,每一項(xiàng)分別是一個 Promise 實(shí)例)提供了并行執(zhí)行異步操作的能力,并且在所有異步操作執(zhí)行完(所有實(shí)例的狀態(tài)都變成 fulfilled)或者 只要有一個 Promise 實(shí)例的狀態(tài)變?yōu)?reject,Promise.all 的狀態(tài)就會變?yōu)?reject,然后執(zhí)行回調(diào)??梢詫?shù)組里的 Promise 看成是 “與” 關(guān)系。

應(yīng)用場景:打開網(wǎng)頁時,預(yù)先加載需要用到的各種資源如圖片、flash 以及各種靜態(tài)文件。所有的都加載完后,我們再進(jìn)行頁面的初始化

//買作業(yè)本
function cutUp() {
? console.log('挑作業(yè)本')
? var p = new Promise(function(resolve, reject) { //做一些異步操作
?? ?console.log('挑好購買作業(yè)本')
? ?? ?resolve('新的作業(yè)本')
? })
? return p
}
? ? ? ??
//買筆
function boil() {
? console.log('挑筆芯')
? var p = new Promise(function(resolve, reject) { //做一些異步操作
? ? console.log('挑好購買筆芯')
? ? resolve('新的筆芯')
? });
? return p
}

Promise.all([cutUp(),boil()]).then(function(res) {
? console.log("寫作業(yè)的工具都買好了")
? console.log(res)
})

// 挑作業(yè)本
// 挑好購買作業(yè)本
// 挑筆芯
// 挑好購買筆芯
// 寫作業(yè)的工具都買好了
// ["新的作業(yè)本", "新的筆芯"]

5. Promise.race()

Promise.race 方法( 傳入一個數(shù)組,每一項(xiàng)分別是 Promise 實(shí)例 )的用法與 all 一樣,異步操作同樣是并行執(zhí)行的。只不過 all 是等所有異步操作都執(zhí)行完畢后才執(zhí)行 then 回調(diào)。race 可以看到 是 “或” 關(guān)系,只要有一個異步操作執(zhí)行完畢,就會立刻執(zhí)行 then 回調(diào)。

應(yīng)用場景:用 race 給某個異步請求設(shè)置超時時間,并且在超時后執(zhí)行相應(yīng)的操作

//買作業(yè)本
function cutUp() {
? console.log('挑作業(yè)本')
? var p = new Promise(function(resolve, reject) { //做一些異步操作
?? ?console.log('挑好購買作業(yè)本')
? ?? ?resolve('新的作業(yè)本')
? })
? return p
}
? ? ? ??
//買筆
function boil() {
? console.log('挑筆芯')
? var p = new Promise(function(resolve, reject){ //做一些異步操作
? ? console.log('挑好購買筆芯')
? ? resolve('新的筆芯')
? })
? return p
}

Promise.race([cutUp(),boil()]).then(function(res){
? console.log("寫作業(yè)的工具都買好了")
? console.log(res)
})

// 挑作業(yè)本
// 挑好購買作業(yè)本
// 挑筆芯
// 挑好購買筆芯
// 寫作業(yè)的工具都買好了
// 新的作業(yè)本

5. Promise.allSettled()

Promise.allSettled() 方法接受一組 Promise 實(shí)例作為參數(shù),包裝成一個新的 Promise 實(shí)例 。

只有等到所有這些參數(shù)實(shí)例都返回結(jié)果,不管是 fulfilled 還是 rejected,包裝實(shí)例才會結(jié)束。

Promise.allSettled()的返回值該是一個數(shù)組,數(shù)組里每個對象都有 status 屬性,該屬性的值只可能是字符串 fulfilled 或字符串rejected。

fulfilled 時,對象有 value 屬性,rejected 時有 reason 屬性,對應(yīng)兩種狀態(tài)的返回值。

應(yīng)用場景:不關(guān)心異步操作的結(jié)果,只確保所有異步操作都結(jié)束

//買作業(yè)本
function cutUp() {
? console.log('挑作業(yè)本')
? var p = new Promise(function(resolve, reject) { //做一些異步操作
?? ?console.log('挑好購買作業(yè)本')
? ?? ?resolve('新的作業(yè)本')
? })
? return p
}
? ? ? ??
//買筆
function boil() {
? console.log('挑筆芯')
? var p = new Promise(function(resolve, reject){ //做一些異步操作
? ? console.log('挑好購買筆芯')
? ? reject('購買不了,沒錢了')
? })
? return p
}

Promise.allSettled([cutUp(),boil()]).then(function(res){
? console.log("寫作業(yè)的工具沒有買齊")
? console.log(res)
})

// 挑作業(yè)本
// 挑好購買作業(yè)本
// 挑筆芯
// 挑好購買筆芯
// 寫作業(yè)的工具沒有買齊
// [
// ? {status: "fulfilled", value: "新的作業(yè)本"}
// ? {status: "rejected", reason: "購買不了,沒錢了"}
// ]

Promise 的簡單封裝

function promiseM(callback) {
? ? this.status = 'pendding'
? ? this.msg = ''

? ? callback((data) => {
? ? ? ? this.status = 'resolve'
? ? ? ? this.msg = data
? ? },(err) => {
? ? if (this.status === 'resolve') return
? ? ? ? this.status = 'reject'
? ? ? ? this.msg = err
? ? })
}

promiseM.prototype.then = function () {
? ? let cb = arguments
? ? let that = this
? ? let timer = setInterval(function () {
? ? ? ? if(that.status == 'resolve') {
? ? ? ? ? ? cb[0](that.msg)
? ? ? ? ? ? clearInterval(timer)
? ? ? ? } else if(that.status == 'reject') {
? ? ? ? ?? ?if(!cb[1]) {
? ? ? ? ?? ??? ?clearInterval(timer)
? ? ? ? ? ? ? ? throw that.msg + ' No Exit'
? ? ? ? ?? ?} else {
? ? ? ? ?? ??? ?cb[1](that.msg)
? ? ? ? ? ? ?? ?clearInterval(timer)
? ? ? ? ?? ?}
? ? ? ? }
? ? }, 500)
}

function fn() {
? ? return new promiseM(function (resolve, reject) {
? ? ? ? resolve('success')
? ? })
}

fn().then(function (res) {
? ? console.log(res)
})

// success

總結(jié)

以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Javascript實(shí)現(xiàn)Web顏色值轉(zhuǎn)換

    Javascript實(shí)現(xiàn)Web顏色值轉(zhuǎn)換

    這篇文章主要介紹了Javascript實(shí)現(xiàn)Web顏色值轉(zhuǎn)換,需要的朋友可以參考下
    2015-02-02
  • 深入理解JavaScript強(qiáng)制類型轉(zhuǎn)換

    深入理解JavaScript強(qiáng)制類型轉(zhuǎn)換

    JavaScript中的強(qiáng)制類型轉(zhuǎn)換包括顯式和隱式轉(zhuǎn)換,涉及字符串、數(shù)字和布爾值三種基本類型,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-09-09
  • 小程序?qū)崿F(xiàn)多個選項(xiàng)卡切換

    小程序?qū)崿F(xiàn)多個選項(xiàng)卡切換

    這篇文章主要為大家詳細(xì)介紹了小程序?qū)崿F(xiàn)多個選項(xiàng)卡切換,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-06-06
  • taro 實(shí)現(xiàn)購物車邏輯的實(shí)例代碼

    taro 實(shí)現(xiàn)購物車邏輯的實(shí)例代碼

    這篇文章主要介紹了taro 實(shí)現(xiàn)購物車邏輯,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-06-06
  • JS實(shí)現(xiàn)獲取剪貼板內(nèi)容的方法

    JS實(shí)現(xiàn)獲取剪貼板內(nèi)容的方法

    這篇文章主要介紹了JS實(shí)現(xiàn)獲取剪貼板內(nèi)容的方法,涉及javascript基于clipboardData操作剪貼板的相關(guān)技巧,需要的朋友可以參考下
    2016-06-06
  • JS獲取鍵盤上任意按鍵的值(實(shí)例代碼)

    JS獲取鍵盤上任意按鍵的值(實(shí)例代碼)

    JS獲取鍵盤上任意按鍵值的實(shí)例代碼。需要的朋友可以過來參考下,希望對大家有所幫助
    2013-11-11
  • 一個簡單的JS鼠標(biāo)懸停特效具體方法

    一個簡單的JS鼠標(biāo)懸停特效具體方法

    這個特效最終實(shí)現(xiàn)效果就是當(dāng)鼠標(biāo)移動到鏈接上,文字會橫向移動一定距離,貌似總有人喜歡這些花花草草。添加此效果方法很簡單。
    2013-06-06
  • 詳解在微信小程序的JS腳本中使用Promise來優(yōu)化函數(shù)處理

    詳解在微信小程序的JS腳本中使用Promise來優(yōu)化函數(shù)處理

    這篇文章主要介紹了詳解在微信小程序的JS腳本中使用Promise來優(yōu)化函數(shù)處理,引入Promise確實(shí)能夠很好的解決異步回調(diào)函數(shù)的可讀性等問題,同時也使得我們調(diào)用的時候代碼簡潔一些,本文介紹如何在小程序的JS代碼里面使用Promise來封裝一些函數(shù)的做法
    2019-03-03
  • JS將時間秒轉(zhuǎn)換成天小時分鐘秒的字符串

    JS將時間秒轉(zhuǎn)換成天小時分鐘秒的字符串

    最近小編接到這樣的項(xiàng)目需求,接口返回的數(shù)據(jù)中時間單位為秒,但前端顯示的時候需要更人性化的帶有單位(天,小時,分鐘,秒)的字符串;下面小編給大家?guī)韺?shí)例代碼,感興趣的朋友跟隨小編一起看看吧
    2019-07-07
  • 通過身份證號得到出生日期和性別的js代碼

    通過身份證號得到出生日期和性別的js代碼

    主要是通過判斷指定位數(shù)的數(shù)字,來判斷并加以算法實(shí)現(xiàn)男女性別的判斷。
    2009-11-11

最新評論