js中promise學(xué)習(xí)

<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8">

<title>promise學(xué)習(xí)</title>

<!-- 在js中,所有代碼都是單線程執(zhí)行的 -->

<!-- 異步執(zhí)行:可以使用回調(diào),在ES6中我們可以使用Promise對(duì)象來實(shí)現(xiàn) -->

<!--

1.1Promise對(duì)象,只需要then一個(gè)方法,then方法帶有如下三個(gè)參數(shù)

? ? 1.成功回調(diào)

? ? 2.失敗回調(diào)

? ? 3.前進(jìn)回調(diào)(暫時(shí)不講)

? ? 一個(gè)全新的 promise 對(duì)象從每個(gè) then 的調(diào)用中返回。

1.2 Promise對(duì)象代表一個(gè)異步操作,其不受外界影響,有三種狀態(tài)

.Pending進(jìn)行中

.Resolved(已完成,又稱Fulfilled)

.Rejected(已失敗)

1.3使用Promise的優(yōu)勢(shì)

1.3.1 解決回調(diào)地獄問題(Callback Hell)

例如,有時(shí)候我們可能會(huì)進(jìn)行多個(gè)異步操作,后一個(gè)的請(qǐng)求需要上一次請(qǐng)求的返回結(jié)果,所以過去我們都是用callback層層嵌套,

但是多了的話就會(huì)出現(xiàn)回調(diào)地獄,代碼的可讀性和維護(hù)性都會(huì)變得很差

firstAsync(function(data){

? ? ? ? ? ? ? ? ? ? ? ? //處理得到的 data 數(shù)據(jù)

//....

secondAsync(function(data2){

//處理得到的 data2 數(shù)據(jù)

//....

thirdAsync(function(data3){

? //處理得到的 data3 數(shù)據(jù)

? //....

});

});

});

1.3.2 使用promise的話,代碼會(huì)變得扁平和可讀.前面提到了then返回一個(gè)promise,因此我們可以將then的調(diào)用不停的串聯(lián)起來,其中then返回的

promise裝載了由調(diào)用返回的值.

firstAsync()

.then(function(data){

//處理得到的 data 數(shù)據(jù)

//....

return secondAsync();

})

.then(function(data2){

//處理得到的 data2 數(shù)據(jù)

//....

return thirdAsync();

})

.then(function(data3){

//處理得到的 data3 數(shù)據(jù)

//....

});

1.3.3 更好的進(jìn)行錯(cuò)誤捕獲

多層嵌套會(huì)造成無法捕獲異常,使用promise,通過使用reject方法把promise的狀態(tài)設(shè)置為rejected,這樣我們?cè)趖hen中就能捕捉到,然后執(zhí)行失敗情況的回調(diào)

function fetch(callback) {

return new Promise((resolve, reject) => {

setTimeout(() => {

reject('請(qǐng)求失敗');

}, 2000)

})

}

fetch()

.then(

function(data){

console.log('請(qǐng)求處理');

console.log(data);

},

function(reason, data){

console.log('觸發(fā)異常');

console.log(reason);

}

);

當(dāng)然我們?cè)赾atch方法中處理reject回調(diào)也是可以的,

function fetch(callback) {

return new Promise((resolve, reject) => {

setTimeout(() => {

reject('請(qǐng)求失敗');

}, 2000)

})

}

fetch()

.then(

function(data){

console.log('請(qǐng)求處理');

console.log(data);

}

)

.catch(function(reason){

console.log('觸發(fā)異常');

console.log(reason);

});

-->

</head>

<body>

<script type="text/javascript">

new Promise(function(resolve, reject) {

console.log('start new Promise...');

var timeOut = Math.random() * 2;

console.log('set timeout to: ' + timeOut + ' seconds.');

setTimeout(function() {

if (timeOut < 10) {

console.log('call resolve()...');

resolve('200 OK');

} else {

console.log('call reject()...');

reject('timeout in ' + timeOut + ' seconds.');

}

}, timeOut * 1000);

}).then(function(r) {

console.log('Done: ' + r);

}).catch(function(reason) {

console.log('Failed: ' + reason);

});

// promise的使用詳解,簡(jiǎn)單來講,then方法就是把原來的回調(diào)寫法分離出來,在異步執(zhí)行操作執(zhí)行完成后,用鏈?zhǔn)秸{(diào)用的方式,回調(diào)函數(shù);

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

// then方法舉例? ? ? ? ? 例如 學(xué)習(xí) 考試? 放假

function study() {

var p = new Promise(function(resolve, reject) {

setTimeout(() => {

resolve("學(xué)習(xí)結(jié)束,開始考試")

}, 2000)

});

return p;

}

function test(data) {

var p = new Promise(function(resolve, reject) {

setTimeout(() => {

resolve("考試結(jié)束,開始假期")

}, 2000)

});

return p;

}

function holiday(data) {

var p = new Promise(function(resolve, reject) {

setTimeout(() => {

resolve("假期結(jié)束,開始上課")

}, 2000)

});

return p;

}

// 使用then鏈?zhǔn)秸{(diào)用這三個(gè)方法

study()

.then(function(data) {

console.log(data)

return test(data);

})

.then(function(data) {

console.log(data)

return holiday(data)

})

.then(function(data) {

console.log(data)

})

// 運(yùn)行結(jié)果

// 學(xué)習(xí)結(jié)束,開始考試

// 試結(jié)束,開始假期

// 假期結(jié)束,開始上課

// 2.reject方法

function learn() {

var p = new Promise(function(reslove, reject) {

setTimeout(() => {

reject("考試不及格")

}, 1000)

});

return p;

}

learn()

.then(test, function(data) {

console.log(data + "無法放假,復(fù)習(xí)吧");

})

// 執(zhí)行結(jié)果

// 考試不及格無法放假,復(fù)習(xí)吧

// 另外如果我們只要處理失敗的情況,可以使用then(null,.....),或者使用catch方法

learn()

.then(null, function(data) {

console.log(data + "無法放假,復(fù)習(xí)吧");

})

// catch方法和then方法的第二個(gè)參數(shù)一樣,用來指定reject的回調(diào)

learn()

.then(test)

.catch(function(data) {

console.log("沒得玩了");

})

// 另一個(gè)作用是,當(dāng)執(zhí)行resolve的回調(diào)時(shí),如果拋出了異常(代碼出錯(cuò)),那么也不會(huì)報(bào)錯(cuò)卡死js,而是會(huì)進(jìn)到這個(gè)catch中

study()

.then(function(data) {

throw new Error("考題泄漏");

test(data)

})

.catch(function(data) {

console.log(data + "無法繼續(xù)考試")

})

// all方法,提供了并行異步執(zhí)行操作的能力,并且在所有異步操作執(zhí)行完后才會(huì)執(zhí)行回調(diào)

// 例如放假要等到學(xué)習(xí)和考試之后

setTimeout(() => {

Promise.all([study(), test(),holiday()])

.then(function(data) {

console.log("開始放假了:后面的是data數(shù)據(jù)? "+data.length+"第一個(gè):"+data[0]+"第二個(gè):"+data[1]+"第三個(gè):"+data[2])

// 打印結(jié)果:? 開始放假了:后面的是data數(shù)據(jù)? 3第一個(gè):學(xué)習(xí)結(jié)束,開始考試第二個(gè):考試結(jié)束,開始假期第三個(gè):假期結(jié)束,開始上課

})

}, 1000)

// race方法,用法與all一樣,只是all是等所有的異步操作完成之后,才會(huì)執(zhí)行then回調(diào).而race回調(diào)的話只要有一個(gè)異步操作執(zhí)行完畢,就立刻執(zhí)行then回調(diào);

//then方法里面的回調(diào)中的參數(shù)data是一個(gè)數(shù)組,我們可以得到異步執(zhí)行操作的結(jié)果

// PS:其他沒有執(zhí)行完畢的異步操作,仍然會(huì)繼續(xù)執(zhí)行,而不是停止

setTimeout(() => {

Promise.race([study(), test()])

.then(function(data) {

console.log("考試不考試,學(xué)習(xí)不學(xué)習(xí),都沒關(guān)系的")

})

}, 20000)

// race的使用場(chǎng)景很多,例如我們可以給某一個(gè)race設(shè)置請(qǐng)求超時(shí)時(shí)間

//考研開始,5s內(nèi)交卷認(rèn)為合格,否則認(rèn)為不合格

function passTheExam() {

var p = new Promise(function(resolve, reject) {

setTimeout(() => {

resolve("交卷")

}, 25000);

})

return p;

}

function requestTimeOut() {

var p = new Promise(function(resolve, reject) {

setTimeout(() => {

reject("考試失敗")

}, 30000);

})

return p;

}

Promise.race([passTheExam(),requestTimeOut()])

.then(function(data){

console.log(data);

})

.catch(function(err){

console.log(err);

})

</script>

</body>

</html>

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Promise 對(duì)象 Promise 的含義 Promise 是異步編程的一種解決方案,比傳統(tǒng)的解決方案——回調(diào)函...
    neromous閱讀 8,835評(píng)論 1 56
  • 一、Promise的含義 Promise在JavaScript語(yǔ)言中早有實(shí)現(xiàn),ES6將其寫進(jìn)了語(yǔ)言標(biāo)準(zhǔn),統(tǒng)一了用法...
    Alex灌湯貓閱讀 888評(píng)論 0 2
  • 本文適用的讀者 本文寫給有一定Promise使用經(jīng)驗(yàn)的人,如果你還沒有使用過Promise,這篇文章可能不適合你,...
    HZ充電大喵閱讀 7,456評(píng)論 6 19
  • 特點(diǎn) Promise能將回調(diào)分離出來,在異步操作執(zhí)行之后,用鏈?zhǔn)椒椒▓?zhí)行回調(diào),雖然es5用封裝函數(shù)也能實(shí)現(xiàn),但是如...
    一二三kkxx閱讀 717評(píng)論 0 1
  • 前言 本文旨在簡(jiǎn)單講解一下javascript中的Promise對(duì)象的概念,特性與簡(jiǎn)單的使用方法。并在文末會(huì)附上一...
    _暮雨清秋_閱讀 2,315評(píng)論 0 3

友情鏈接更多精彩內(nèi)容