中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

讓你徹底掌握es6 Promise的八段代碼

發布時間:2020-08-23 06:33:03 來源:腳本之家 閱讀:163 作者:xuchaobei 欄目:web開發

前言

新的ES6中引入了promise的概念,目的是讓回調更為優雅。層層嵌套的回調會讓javascript失去美感和可讀性,同時javascript也推薦采用鏈式的方式去書寫函數調用。于是Promise就應運而生。本文將通過八段代碼讓大家徹底的掌握Promise,下面話不多說,來一起看看詳細的介紹:

1.Promise的立即執行性

var p = new Promise(function(resolve, reject){
 console.log("create a promise");
 resolve("success");
});

console.log("after new Promise");

p.then(function(value){
 console.log(value);
});

控制臺輸出:

"create a promise"
"after new Promise"
"success"

Promise對象表示未來某個將要發生的事件,但在創建(new)Promise時,作為Promise參數傳入的函數是會被立即執行的,只是其中執行的代碼可以是異步代碼。有些同學會認為,當Promise對象調用then方法時,Promise接收的函數才會執行,這是錯誤的。因此,代碼中"create a promise"先于"after new Promise"輸出。

2.Promise 三種狀態

var p1 = new Promise(function(resolve,reject){
 resolve(1);
});
var p2 = new Promise(function(resolve,reject){
 setTimeout(function(){
 resolve(2); 
 }, 500); 
});
var p3 = new Promise(function(resolve,reject){
 setTimeout(function(){
 reject(3); 
 }, 500); 
});

console.log(p1);
console.log(p2);
console.log(p3);
setTimeout(function(){
 console.log(p2);
}, 1000);
setTimeout(function(){
 console.log(p3);
}, 1000);

p1.then(function(value){
 console.log(value);
});
p2.then(function(value){
 console.log(value);
});
p3.catch(function(err){
 console.log(err);
});

控制臺輸出:

Promise {[[PromiseStatus]]: "resolved", [[PromiseValue]]: 1}
Promise {[[PromiseStatus]]: "pending", [[PromiseValue]]: undefined}
Promise {[[PromiseStatus]]: "pending", [[PromiseValue]]: undefined}
1
2
3
Promise {[[PromiseStatus]]: "resolved", [[PromiseValue]]: 2}
Promise {[[PromiseStatus]]: "rejected", [[PromiseValue]]: 3}

Promise的內部實現是一個狀態機。Promise有三種狀態:pending,resolved,rejected。當Promise剛創建完成時,處于pending狀態;當Promise中的函數參數執行了resolve后,Promise由pending狀態變成resolved狀態;如果在Promise的函數參數中執行的不是resolve方法,而是reject方法,那么Promise會由pending狀態變成rejected狀態。

p2、p3剛創建完成時,控制臺輸出的這兩臺Promise都處于pending狀態,但為什么p1是resolved狀態呢? 這是因為p1 的函數參數中執行的是一段同步代碼,Promise剛創建完成,resolve方法就已經被調用了,因而緊跟著的輸出顯示p1是resolved狀態。我們通過兩個setTimeout函數,延遲1s后再次輸出p2、p3的狀態,此時p2、p3已經執行完成,狀態分別變成resolved和rejected。

3.Promise 狀態的不可逆性

var p1 = new Promise(function(resolve, reject){
 resolve("success1");
 resolve("success2");
});

var p2 = new Promise(function(resolve, reject){
 resolve("success");
 reject("reject");
});

p1.then(function(value){
 console.log(value);
});

p2.then(function(value){
 console.log(value);
});

控制臺輸出:

"success1"
"success"

Promise狀態的一旦變成resolved或rejected時,Promise的狀態和值就固定下來了,不論你后續再怎么調用resolve或reject方法,都不能改變它的狀態和值。因此,p1中resolve("success2")并不能將p1的值更改為success2,p2中reject("reject")也不能將p2的狀態由resolved改變為rejected.

4.鏈式調用

var p = new Promise(function(resolve, reject){
 resolve(1);
});
p.then(function(value){ //第一個then
 console.log(value);
 return value*2;
}).then(function(value){ //第二個then
 console.log(value);
}).then(function(value){ //第三個then
 console.log(value);
 return Promise.resolve('resolve'); 
}).then(function(value){ //第四個then
 console.log(value);
 return Promise.reject('reject');
}).then(function(value){ //第五個then
 console.log('resolve: '+ value);
}, function(err){
 console.log('reject: ' + err);
})

控制臺輸出:

1
2
undefined
"resolve"
"reject: reject"

Promise對象的then方法返回一個新的Promise對象,因此可以通過鏈式調用then方法。then方法接收兩個函數作為參數,第一個參數是Promise執行成功時的回調,第二個參數是Promise執行失敗時的回調。兩個函數只會有一個被調用,函數的返回值將被用作創建then返回的Promise對象。這兩個參數的返回值可以是以下三種情況中的一種:

  • return 一個同步的值 ,或者 undefined(當沒有返回一個有效值時,默認返回undefined),then方法將返回一個resolved狀態的Promise對象,Promise對象的值就是這個返回值。
  • return 另一個 Promise,then方法將根據這個Promise的狀態和值創建一個新的Promise對象返回。
  • throw 一個同步異常,then方法將返回一個rejected狀態的Promise, 值是該異常。

根據以上分析,代碼中第一個then會返回一個值為2(1*2),狀態為resolved的Promise對象,于是第二個then輸出的值是2。第二個then中沒有返回值,因此將返回默認的undefined,于是在第三個then中輸出undefined。第三個then和第四個then中分別返回一個狀態是resolved的Promise和一個狀態是rejected的Promise,依次由第四個then中成功的回調函數和第五個then中失敗的回調函數處理。

5.Promise then() 回調異步性

var p = new Promise(function(resolve, reject){
 resolve("success");
});

p.then(function(value){
 console.log(value);
});

console.log("which one is called first ?");

控制臺輸出:

"which one is called first ?"
"success"

Promise接收的函數參數是同步執行的,但then方法中的回調函數執行則是異步的,因此,"success"會在后面輸出。

6.Promise 中的異常

var p1 = new Promise( function(resolve,reject){
 foo.bar();
 resolve( 1 ); 
});

p1.then(
 function(value){
 console.log('p1 then value: ' + value);
 },
 function(err){
 console.log('p1 then err: ' + err);
 }
).then(
 function(value){
 console.log('p1 then then value: '+value);
 },
 function(err){
 console.log('p1 then then err: ' + err);
 }
);

var p2 = new Promise(function(resolve,reject){
 resolve( 2 ); 
});

p2.then(
 function(value){
 console.log('p2 then value: ' + value);
 foo.bar();
 }, 
 function(err){
 console.log('p2 then err: ' + err);
 }
).then(
 function(value){
 console.log('p2 then then value: ' + value);
 },
 function(err){
 console.log('p2 then then err: ' + err);
 return 1;
 }
).then(
 function(value){
 console.log('p2 then then then value: ' + value);
 },
 function(err){
 console.log('p2 then then then err: ' + err);
 }
);

控制臺輸出:

p1 then err: ReferenceError: foo is not defined
p2 then value: 2
p1 then then value: undefined
p2 then then err: ReferenceError: foo is not defined
p2 then then then value: 1

Promise中的異常由then參數中第二個回調函數(Promise執行失敗的回調)處理,異常信息將作為Promise的值。異常一旦得到處理,then返回的后續Promise對象將恢復正常,并會被Promise執行成功的回調函數處理。另外,需要注意p1、p2 多級then的回調函數是交替執行的 ,這正是由Promise then回調的異步性決定的。

7.Promise.resolve()

var p1 = Promise.resolve( 1 );
var p2 = Promise.resolve( p1 );
var p3 = new Promise(function(resolve, reject){
 resolve(1);
});
var p4 = new Promise(function(resolve, reject){
 resolve(p1);
});

console.log(p1 === p2); 
console.log(p1 === p3);
console.log(p1 === p4);
console.log(p3 === p4);

p4.then(function(value){
 console.log('p4=' + value);
});

p2.then(function(value){
 console.log('p2=' + value);
})

p1.then(function(value){
 console.log('p1=' + value);
})

控制臺輸出:

true
false
false
false
p2=1
p1=1
p4=1

Promise.resolve(...)可以接收一個值或者是一個Promise對象作為參數。當參數是普通值時,它返回一個resolved狀態的Promise對象,對象的值就是這個參數;當參數是一個Promise對象時,它直接返回這個Promise參數。因此,p1 === p2。但通過new的方式創建的Promise對象都是一個新的對象,因此后面的三個比較結果都是false。另外,為什么p4的then最先調用,但在控制臺上是最后輸出結果的呢?因為p4的resolve中接收的參數是一個Promise對象p1,resolve會對p1”拆箱“,獲取p1的狀態和值,但這個過程是異步的,可參考下一節。

8.resolve vs reject

var p1 = new Promise(function(resolve, reject){
 resolve(Promise.resolve('resolve'));
});

var p2 = new Promise(function(resolve, reject){
 resolve(Promise.reject('reject'));
});

var p3 = new Promise(function(resolve, reject){
 reject(Promise.resolve('resolve'));
});

p1.then(
 function fulfilled(value){
 console.log('fulfilled: ' + value);
 }, 
 function rejected(err){
 console.log('rejected: ' + err);
 }
);

p2.then(
 function fulfilled(value){
 console.log('fulfilled: ' + value);
 }, 
 function rejected(err){
 console.log('rejected: ' + err);
 }
);

p3.then(
 function fulfilled(value){
 console.log('fulfilled: ' + value);
 }, 
 function rejected(err){
 console.log('rejected: ' + err);
 }
);

控制臺輸出:

p3 rejected: [object Promise]
p1 fulfilled: resolve
p2 rejected: reject

Promise回調函數中的第一個參數resolve,會對Promise執行"拆箱"動作。即當resolve的參數是一個Promise對象時,resolve會"拆箱"獲取這個Promise對象的狀態和值,但這個過程是異步的。p1"拆箱"后,獲取到Promise對象的狀態是resolved,因此fulfilled回調被執行;p2"拆箱"后,獲取到Promise對象的狀態是rejected,因此rejected回調被執行。但Promise回調函數中的第二個參數reject不具備”拆箱“的能力,reject的參數會直接傳遞給then方法中的rejected回調。因此,即使p3 reject接收了一個resolved狀態的Promise,then方法中被調用的依然是rejected,并且參數就是reject接收到的Promise對象。

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對億速云的支持。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

梅河口市| 松潘县| 阿坝县| 灵山县| 乾安县| 墨竹工卡县| 伊宁县| 凤阳县| 新和县| 牙克石市| 吴旗县| 福鼎市| 梧州市| 阿勒泰市| 溧水县| 定陶县| 中山市| 马山县| 旬邑县| 云安县| 罗源县| 江西省| 仙居县| 乐陵市| 永济市| 马边| 宜都市| 海伦市| 镶黄旗| 景泰县| 博湖县| 平邑县| 兴海县| 界首市| 北流市| 亳州市| 铜梁县| 冀州市| 岳阳市| 永平县| 格尔木市|