摘要:三種狀態(tài)進(jìn)行中已完成,又稱(chēng)已失敗。如果的狀態(tài)是,那么的回調(diào)函數(shù)就會(huì)等待的狀態(tài)改變,在此之前不會(huì)有結(jié)果。等價(jià)于例子例子的概念是實(shí)例的別名,用于指定發(fā)生錯(cuò)誤時(shí)的回調(diào)函數(shù)。
『ES6知識(shí)點(diǎn)總結(jié)』變量的解構(gòu)賦值
本文主要內(nèi)容如下:
1 Promise是什么?
1.1 特點(diǎn):
1.2 三種狀態(tài):
1.3 用處:
1.4 Promise缺點(diǎn):
1.5 歷史過(guò)程
2 生成promise實(shí)例
3 promise實(shí)例的then()方法
4 resolve函數(shù)的參數(shù)可以是另一個(gè)Promise實(shí)例
5 Promise的方法(多種)
5.1 Promise.all()
5.2 Promise.race()
5.3 Promise.reject(reason)
5.4 Promise.resolve(obj)
6 Promise.prototype.catch()的概念
6.1 盡量不定義then的reject方法
6.2 catch方法返回的還是一個(gè)Promise對(duì)象,因此后面還可以接著調(diào)用then方法。
7
7.1 如果前面的promise和then()沒(méi)有報(bào)錯(cuò),則會(huì)跳過(guò)catch方法。
7.2 拋錯(cuò)的冒泡性質(zhì)
7.2.1 如果Promise狀態(tài)已經(jīng)變成resolved,再拋出錯(cuò)誤是無(wú)效的。
7.2.2 Promise在下一輪“事件循環(huán)”再拋出錯(cuò)誤
7.2.3 如果沒(méi)有處理錯(cuò)誤的回調(diào)函數(shù),就沒(méi)有反應(yīng)
7.2.4 catch方法之中,還能再拋出錯(cuò)誤。
8 node.js的unhandledRejection
9 done()
10 finally()
Promise是什么?
01、是一個(gè)對(duì)象,用來(lái)傳遞異步操作的消息。
02、代表了某個(gè)未來(lái)才會(huì)知道結(jié)果的事件(通常是一個(gè)異步操作)。
03、提供一個(gè)統(tǒng)一的API,可以進(jìn)一步處理,控制異步操作。
特點(diǎn):
01、對(duì)象的狀態(tài)不受外界影響。
02、代表一個(gè)異步操作。
三種狀態(tài):
Pending(進(jìn)行中) Resolved(已完成,又稱(chēng)Fulfilled) Rejected(已失?。?。
(1)默認(rèn)的Promise對(duì)象是等待態(tài)(Pending)。
只有異步操作的結(jié)果,可以決定當(dāng)前是哪一種狀態(tài),任何其他操作都無(wú)法改變這個(gè)狀態(tài)。
這也是Promise這個(gè)名字的由來(lái),它的英語(yǔ)意思就是“許諾”,表示其他手段無(wú)法改變。
(2)一旦狀態(tài)改變了,就不會(huì)再變了,會(huì)一直保持這個(gè)結(jié)果。
任何時(shí)候都可以得到這個(gè)結(jié)果。
Promise對(duì)象的狀態(tài)改變,只有兩種:
從Pending變?yōu)镽esolved。 從Pending變?yōu)镽ejected。
這與事件(Event)不同,事件的特點(diǎn)是,如果你錯(cuò)過(guò)了它,再去監(jiān)聽(tīng),是得不到結(jié)果的。
用處:
用Promise對(duì)象可以將異步操作以同步操作的流程表達(dá)出來(lái),避免了層層嵌套的回調(diào)函數(shù)。
可以判斷多個(gè)異步事件的完成,
Promise缺點(diǎn):
無(wú)法取消Promise,一旦新建它就會(huì)立即執(zhí)行,無(wú)法中途取消。
如果不設(shè)置回調(diào)函數(shù),Promise內(nèi)部拋出的錯(cuò)誤,不會(huì)反應(yīng)到外部。
當(dāng)處于Pending狀態(tài)時(shí),無(wú)法得知目前進(jìn)展到哪一個(gè)階段(剛剛開(kāi)始還是即將完成)。
歷史過(guò)程
生成promise實(shí)例
Promise是一個(gè)構(gòu)造函數(shù),可以生成Promise實(shí)例。
接受一個(gè)函數(shù)A作為參數(shù),該函數(shù)A有2個(gè)參數(shù),是resolve和reject(拒絕),它們是函數(shù),由JS引擎提供,不用自己部署。
resolve(value)函數(shù)的作用是,將Promise對(duì)象的狀態(tài)從“未完成”變?yōu)椤俺晒Α保磸腜ending變?yōu)镽esolved),在異步操作成功時(shí)被調(diào)用,并將異步操作的結(jié)果,作為自己的參數(shù)。
reject(error)函數(shù)的作用是,將Promise對(duì)象的狀態(tài)從“未完成”變?yōu)椤笆 保磸腜ending變?yōu)镽ejected),在異步操作失敗時(shí)調(diào)用,并將異步操作報(bào)出的錯(cuò)誤,作為自己的參數(shù)。
reject函數(shù)的參數(shù)通常是Error對(duì)象的實(shí)例,表示拋出的錯(cuò)誤。
例子:
reject(new Error(this.statusText));
在promise實(shí)例的構(gòu)造函數(shù)中,可以只返回resolve(value)或reject(error);
例子:
let pro = new Promise((resolve,reject)=>{resolve(value)});
寫(xiě)法:
創(chuàng)造了一個(gè)Promise實(shí)例。
const promise = new Promise(function(resolve, reject) { if ( /* 異步操作成功 */ ) { resolve(value); } else { reject(error); } });
promise實(shí)例的then()方法
這個(gè)方法在實(shí)例的狀態(tài)改變時(shí)會(huì)觸發(fā)它的參數(shù)函數(shù)。
當(dāng)promise實(shí)例轉(zhuǎn)為成功(Resolved)狀態(tài)時(shí),觸發(fā)then()的第一個(gè)函數(shù)參數(shù)。
當(dāng)promise實(shí)例轉(zhuǎn)為失敗(Rejected)狀態(tài)時(shí),觸發(fā)then()的第二個(gè)函數(shù)參數(shù)。(第二個(gè)函數(shù)參數(shù)可選)
這兩個(gè)函數(shù)參數(shù)都接受promise實(shí)例傳出的值作為參數(shù)。也就是resolve(value)和reject(value)的value值。
then()方法是定義在原型對(duì)象Promise.prototype上的,被所有promise實(shí)例繼承。
promise.then( function (value) { // success }, function (value) { // failure } );
箭頭函數(shù)方式:
promise.then( (value)=>{}, (error)=>{} )
如果then()中有設(shè)置新的promise實(shí)例,則then()方法返回這個(gè)promise對(duì)象。
否則將默認(rèn)構(gòu)建一個(gè)新的promise對(duì)象,并繼承調(diào)用then()方法的promise的狀態(tài)(成功或失?。?。
then方法return返回的是一個(gè)新的Promise實(shí)例(注意,不是原來(lái)那個(gè)Promise實(shí)例)。
因此可以采用鏈?zhǔn)綄?xiě)法,即then方法后面再調(diào)用另一個(gè)then方法。
這個(gè)函數(shù)返回undefined,則then()方法構(gòu)建一個(gè)默認(rèn)的Promise對(duì)象,并且這個(gè)對(duì)象擁有then()方法所屬的Promise對(duì)象的狀態(tài)。
var p = new Promise(function (resolve) { resolve();//直接標(biāo)志執(zhí)行態(tài) }), temp; temp = p.then(function () { //傳入執(zhí)行態(tài)函數(shù),不返回值 }); temp.then(function () { console.log("fulfilled");//擁有p的狀態(tài) }); console.log(temp === p);//默認(rèn)構(gòu)建的promise,但已經(jīng)和p不是同一個(gè)對(duì)象,輸出false
如果對(duì)應(yīng)狀態(tài)所執(zhí)行的函數(shù)返回一個(gè)全新的Promise對(duì)象,則會(huì)覆蓋掉當(dāng)前Promise,代碼如下:
var p = new Promise(function (resolve) { resolve();//直接標(biāo)志執(zhí)行態(tài) }), temp; temp = p.then(function () { //返回新的promise對(duì)象,和p的狀態(tài)無(wú)關(guān) return new Promise(function (resolve, reject) { reject();//標(biāo)志拒絕態(tài) }); }); temp.then(function () { console.log("fulfilled"); }, function () { console.log("rejected");//輸出rejected });
resolve函數(shù)的參數(shù)可以是另一個(gè)Promise實(shí)例
表示當(dāng)前異步操作的取決于另一個(gè)異步操作的結(jié)果。
舉個(gè)例子來(lái)說(shuō),張三到李四家拿鑰匙,取決于李四在家不在家。
如果李四在家,那么張三可以成功拿到鑰匙。如果李四不在家,張三就拿不到鑰匙。
有2個(gè)promise實(shí)例p1和p2,
p2的resolve(p1),那么,p1的狀態(tài)決定了p2的狀態(tài)。
如果p1的狀態(tài)是Pending,那么p2的回調(diào)函數(shù)就會(huì)等待p1的狀態(tài)改變,在此之前不會(huì)有結(jié)果。
如果p1的狀態(tài)已經(jīng)是Resolved或者Rejected,那么p2的回調(diào)函數(shù)將會(huì)立刻執(zhí)行。
比如像下面這樣。
var p1 = new Promise(function(resolve, reject) { // ...}); var p2 = new Promise(function(resolve, reject) { // ... resolve(p1); })
【】例子:
p1是一個(gè)Promise,3秒之后變?yōu)閞ejected。p2的狀態(tài)由p1決定,1秒之后,p2調(diào)用resolve方法,但是此時(shí)p1的狀態(tài)還沒(méi)有改變,因此p2的狀態(tài)也不會(huì)變。又過(guò)了2秒,p1變?yōu)閞ejected,p2也跟著變?yōu)閞ejected。
var p1 = new Promise(function(resolve, reject) { setTimeout(() => reject(new Error("fail")), 3000); }); var p2 = new Promise(function(resolve, reject) { setTimeout(() => resolve(p1), 1000) }); p2.then(result => console.log(result)) p2.catch(error => console.log(error)) // Error: fail
【】例子:
下面是一個(gè)Promise對(duì)象的簡(jiǎn)單例子。
timeout函數(shù)中,會(huì)返回新生成的Promise實(shí)例,其中,定時(shí)器setTimeout會(huì)在100ms后調(diào)用resolve("done");當(dāng)調(diào)用resolve后,觸發(fā)then綁定的回調(diào)函數(shù)。
zyx456:"done"是resolve的參數(shù)。
等效于:
function timeout(ms) { return new Promise((resolve, reject) => { setTimeout(resolve("done"),ms); }); } timeout(100).then((value) => { console.log(value); });
【】例子:
下面是異步加載圖片的例子。
function loadImageAsync(url) {
return new Promise(function(resolve, reject) { var image = new Image(); image.onload = function() { resolve(image); }; image.onerror = function() { reject(new Error("Could not load image at " + url)); }; image.src = url; });
}
【】例子:
下面是一個(gè)用Promise對(duì)象實(shí)現(xiàn)的Ajax操作的例子。
getJSON是對(duì)XMLHttpRequest對(duì)象的封裝,用于發(fā)出一個(gè)針對(duì)JSON數(shù)據(jù)的HTTP請(qǐng)求,并且返回一個(gè)Promise對(duì)象。
var getJSON = function (url) { var promise = new Promise(function (resolve, reject) { var client = new XMLHttpRequest(); client.open("GET", url); client.onreadystatechange = handler; client.responseType = "json"; client.setRequestHeader("Accept", "application/json"); client.send(); function handler() { if (this.readyState !== 4) { return; } if (this.status === 200) { resolve(this.response); } else { reject(new Error(this.statusText)); } }; }); return promise; }; getJSON("/posts.json").then(function (json) { console.log("Contents: " + json); }, function (error) { console.error("出錯(cuò)了", error); });
箭頭函數(shù)寫(xiě)法:
getJSON("/post/1.json").then( post => getJSON(post.commentURL)).then( comments => console.log("Resolved: ", comments), err => console.log("Rejected: ", err));
Promise的方法(多種)
Promise.all()
【01】用于將多個(gè)Promise實(shí)例,包裝成一個(gè)新的Promise實(shí)例。
接受一個(gè)數(shù)組作為參數(shù),數(shù)組元素都是Promise實(shí)例。
如果參數(shù)不是Promise實(shí)例,會(huì)調(diào)用Promise.resolve()轉(zhuǎn)變?yōu)镻romise實(shí)例。
Promise.all()方法的參數(shù)不一定是數(shù)組,但是必須具有iterator接口,且返回的每個(gè)成員都是Promise實(shí)例。
【】返回的新的Promise實(shí)例的狀態(tài):
所有Promise參數(shù)的都變成Resolved,p的狀態(tài)才會(huì)變成Resolved,參數(shù)的返回值組成一個(gè)數(shù)組,傳遞給p的回調(diào)函數(shù)。
只要有一個(gè)參數(shù)被rejected,p的狀態(tài)就變成rejected,此時(shí)第一個(gè)reject的實(shí)例的返回值,會(huì)傳遞給p的回調(diào)函數(shù)。
(小z:類(lèi)似于且操作,且假或真,只有所有的是成功的才可以。你想想,一系列的操作只有都成功才叫成功。)
var p = Promise.all([p1,p2,p3]);
例子
// 生成一個(gè)Promise對(duì)象的數(shù)組 var promises = [2, 3, 5, 7, 8].map(function(id){return getJSON("/post/" + id + ".json");}); Promise.all(promises).then(function(posts) { // ... }).catch(function(reason){ // ... });
Promise.race()
race:賽跑。
【01】將多個(gè)Promise實(shí)例,包裝成一個(gè)新的Promise實(shí)例。
返回這個(gè)新promise實(shí)例,新promise實(shí)例的狀態(tài)為第一個(gè)改變的參數(shù)實(shí)例的狀態(tài)。它的值也是該參數(shù)實(shí)例傳遞出來(lái)的值。
03,參數(shù)如果不是Promise實(shí)例,就會(huì)調(diào)用Promise.resolve方法,將參數(shù)轉(zhuǎn)為Promise實(shí)例,再進(jìn)一步處理。
var p = Promise.race([p1,p2,p3]);
例子:
var p = Promise.race([ fetch("/resource-that-may-take-a-while"), new Promise(function (resolve, reject) { setTimeout(() => reject(new Error("request timeout")), 5000) })]) p.then(response => console.log(response)) p.catch(error => console.log(error))
Promise.reject(reason)
【】會(huì)返回一個(gè)新的Promise實(shí)例,該實(shí)例的狀態(tài)為rejected。
參數(shù)reason,會(huì)被傳遞給實(shí)例的回調(diào)函數(shù)。
var p = Promise.reject("出錯(cuò)了"); // 等同于 var p = new Promise((resolve, reject) => reject("foo")) p.then(null, function (s){ console.log(s)});// 出錯(cuò)了
Promise.resolve(obj)
【01】將對(duì)象轉(zhuǎn)為Promise對(duì)象。
如果參數(shù)不是具有then方法的對(duì)象(又稱(chēng)thenable對(duì)象),則返回一個(gè)新的Promise對(duì)象,且它的狀態(tài)為Resolved。
比如:參數(shù)為字符串時(shí),不屬于異步操作(判斷方法是它不是具有then方法的對(duì)象),所以等價(jià)于Promise構(gòu)造函數(shù)立即執(zhí)行resolve("str");
03,如果沒(méi)有參數(shù),可以得到一個(gè)Promise對(duì)象。
04,如果參數(shù)是一個(gè)Promise實(shí)例,則會(huì)被原封不動(dòng)地返回。
var jsPromise = Promise.resolve($.ajax("/whatever.json"));
Promise.resolve等價(jià)于下面的寫(xiě)法。
Promise.resolve("foo") // 等價(jià)于 new Promise(resolve => resolve("foo"))
例子:
var p = Promise.resolve("Hello"); p.then(function (s){console.log(s)});// Hello
例子:
var p = Promise.resolve(); p.then(function () { // ...});
Promise.prototype.catch()的概念
【01】是 promise實(shí)例.then(null, rejection) 的別名,用于指定發(fā)生錯(cuò)誤時(shí)的回調(diào)函數(shù)。
【】例子:
getJSON方法返回一個(gè)Promise對(duì)象,如果該對(duì)象狀態(tài)變?yōu)镽esolved,則會(huì)調(diào)用then方法指定的回調(diào)函數(shù);
如果異步操作拋出錯(cuò)誤,狀態(tài)就會(huì)變?yōu)镽ejected,就會(huì)調(diào)用catch方法指定的回調(diào)函數(shù),處理這個(gè)錯(cuò)誤。
getJSON("/posts.json").then(function(posts) { // ... }).catch(function(error) { // 處理前一個(gè)回調(diào)函數(shù)運(yùn)行時(shí)發(fā)生的錯(cuò)誤 console.log("發(fā)生錯(cuò)誤!", error); });
例子:
p.then((val) => console.log("fulfilled:", val)).catch((err) => console.log("rejected:", err)); // 等同于 p.then((val) => console.log(fulfilled: ", val)).then(null, (err) => console.log(" rejected: ", err));
例子:
Promise拋出一個(gè)錯(cuò)誤,就被catch方法指定的回調(diào)函數(shù)捕獲。
var promise = new Promise(function(resolve, reject) { throw new Error("test") }); promise.catch(function(error) { console.log(error) });// Error: test
盡量不定義then的reject方法
一般來(lái)說(shuō),不要在then方法里面定義Reject狀態(tài)的回調(diào)函數(shù)(即then的第二個(gè)參數(shù)),總是使用catch方法。
第二種寫(xiě)法要好于第一種寫(xiě)法,理由是前者更接近同步的寫(xiě)法(try/catch)。
// bad promise .then(function(data) { // success }, function(err) { // error }); // good promise .then(function(data) { //cb // success }).catch(function(err) { // error });
catch方法返回的還是一個(gè)Promise對(duì)象,因此后面還可以接著調(diào)用then方法。
var someAsyncThing = function() { return new Promise(function(resolve, reject) { // 下面一行會(huì)報(bào)錯(cuò),因?yàn)閤沒(méi)有聲明 resolve(x + 2); }); }; someAsyncThing().catch(function(error) { console.log("oh no", error); }).then(function() { console.log("carry on"); }); // oh no [ReferenceError: x is not defined] // carry on
如果前面的promise和then()沒(méi)有報(bào)錯(cuò),則會(huì)跳過(guò)catch方法。
Promise.resolve().catch(function(error) { console.log("oh no", error); }).then(function() { console.log("carry on"); }); // carry on
拋錯(cuò)的冒泡性質(zhì)
Promise對(duì)象的錯(cuò)誤具有“冒泡”性質(zhì),會(huì)一直向后傳遞,直到被捕獲為止。
也就是說(shuō),錯(cuò)誤總是會(huì)被下一個(gè)catch語(yǔ)句捕獲。
例子:
一共有三個(gè)Promise對(duì)象:一個(gè)由getJSON產(chǎn)生,兩個(gè)由then產(chǎn)生。它們之中任何一個(gè)拋出的錯(cuò)誤,都會(huì)被最后一個(gè)catch捕獲。
getJSON("/post/1.json").then(function(post) {
return getJSON(post.commentURL); }).then(function(comments) { // some code
}).catch(function(error) { // 處理前面三個(gè)Promise產(chǎn)生的錯(cuò)誤
});
如果Promise狀態(tài)已經(jīng)變成resolved,再拋出錯(cuò)誤是無(wú)效的。
Promise在resolve語(yǔ)句后面,再拋出錯(cuò)誤,不會(huì)被捕獲,等于沒(méi)有拋出。
var promise = new Promise(function(resolve, reject) {
resolve("ok");
throw new Error("test"); });
promise.then(function(value) { console.log(value) }).catch(function(error) { console.log(error) });// ok
Promise在下一輪“事件循環(huán)”再拋出錯(cuò)誤
結(jié)果由于沒(méi)有指定使用try...catch語(yǔ)句,就冒泡到最外層,成了未捕獲的錯(cuò)誤。
因?yàn)榇藭r(shí),Promise的函數(shù)體已經(jīng)運(yùn)行結(jié)束了,所以這個(gè)錯(cuò)誤是在Promise函數(shù)體外拋出的。
var promise = new Promise(function(resolve, reject) { resolve("ok"); setTimeout(function() { throw new Error("test") }, 0) }); promise.then(function(value) { console.log(value) }); // ok // Uncaught Error: test
如果沒(méi)有處理錯(cuò)誤的回調(diào)函數(shù),就沒(méi)有反應(yīng)
跟傳統(tǒng)的try/catch代碼塊不同的是,如果沒(méi)有使用catch方法指定錯(cuò)誤處理的回調(diào)函數(shù),Promise對(duì)象拋出的錯(cuò)誤不會(huì)傳遞到外層代碼,即不會(huì)有任何反應(yīng)。
someAsyncThing函數(shù)產(chǎn)生的Promise對(duì)象會(huì)報(bào)錯(cuò),但是由于沒(méi)有指定catch方法,這個(gè)錯(cuò)誤不會(huì)被捕獲,也不會(huì)傳遞到外層代碼,導(dǎo)致運(yùn)行后沒(méi)有任何輸出。
var someAsyncThing = function() { return new Promise(function(resolve, reject) { // 下面一行會(huì)報(bào)錯(cuò),因?yàn)閤沒(méi)有聲明 resolve(x + 2); }); }; someAsyncThing().then(function() { console.log("everything is great"); });
catch方法之中,還能再拋出錯(cuò)誤。
catch方法拋出一個(gè)錯(cuò)誤,因?yàn)楹竺鏇](méi)有別的catch方法了,導(dǎo)致這個(gè)錯(cuò)誤不會(huì)被捕獲,也不會(huì)傳遞到外層。
var someAsyncThing = function() { return new Promise(function(resolve, reject) { // 下面一行會(huì)報(bào)錯(cuò),因?yàn)閤沒(méi)有聲明 resolve(x + 2); }); }; someAsyncThing().then(function() { return someOtherAsyncThing(); }).catch(function(error) { console.log("oh no", error); // 下面一行會(huì)報(bào)錯(cuò),因?yàn)閥沒(méi)有聲明 y + 2; }).then(function() { console.log("carry on"); }); // oh no [ReferenceError: x is not defined]
如果改寫(xiě)一下,結(jié)果就不一樣了。
第二個(gè)catch方法用來(lái)捕獲,前一個(gè)catch方法拋出的錯(cuò)誤。
someAsyncThing().then(function() { return someOtherAsyncThing(); }).catch(function(error) { console.log("oh no", error); // 下面一行會(huì)報(bào)錯(cuò),因?yàn)閥沒(méi)有聲明 y + 2; }).catch(function(error) { console.log("carry on", error); }); // oh no [ReferenceError: x is not defined] // carry on [ReferenceError: y is not defined]
node.js的unhandledRejection
Node.js有一個(gè)unhandledRejection事件,專(zhuān)門(mén)監(jiān)聽(tīng)未捕獲的reject錯(cuò)誤。
unhandledRejection事件的監(jiān)聽(tīng)函數(shù)有兩個(gè)參數(shù),第一個(gè)是錯(cuò)誤對(duì)象,第二個(gè)是報(bào)錯(cuò)的Promise實(shí)例,它可以用來(lái)了解發(fā)生錯(cuò)誤的環(huán)境信息。
process.on("unhandledRejection", function (err, p) { console.error(err.stack)});
done()
Promise對(duì)象的回調(diào)鏈,不管以then方法或catch方法結(jié)尾,要是最后一個(gè)方法拋出錯(cuò)誤,都有可能會(huì)漏掉(Promise內(nèi)部的錯(cuò)誤不會(huì)冒泡到全局)。
因此,我們可以提供一個(gè)done方法,總是處于回調(diào)鏈的尾端,保證拋出任何可能出現(xiàn)的錯(cuò)誤。
asyncFunc().then(f1).catch(r1).then(f2).done();
done方法的使用,可以像then方法那樣用,提供Fulfilled和Rejected狀態(tài)的回調(diào)函數(shù),也可以不提供任何參數(shù)。但不管怎樣,done都會(huì)捕捉到任何可能出現(xiàn)的錯(cuò)誤,并向全局拋出。
實(shí)現(xiàn)代碼:
Promise.prototype.done = function (resolve, reject) { this.then(resolve, reject).catch(function (reason) { // 拋出一個(gè)全局錯(cuò)誤 setTimeout(() => { throw reason }, 0); }); };
finally()
finally方法用于指定不管Promise對(duì)象最后狀態(tài)如何,都會(huì)執(zhí)行的操作。
它與done方法的最大區(qū)別,它接受一個(gè)普通的回調(diào)函數(shù)作為參數(shù),該函數(shù)不管怎樣都必須執(zhí)行。
等效于,運(yùn)行一個(gè)then(),在成功和失敗回調(diào)函數(shù)中,都要運(yùn)行callback(),
在Promise.resolve()中運(yùn)行callback()后,在運(yùn)行then(),返回結(jié)果。
下面是一個(gè)例子,服務(wù)器使用Promise處理請(qǐng)求,然后使用finally方法關(guān)掉服務(wù)器。
server.listen(0).then(function () { // run test }).finally(server.stop);
它的實(shí)現(xiàn):
Promise.prototype.finally = function(callback) { return this.then( value => Promise.resolve( callback() ).then(() => value), reason => Promise.resolve(callback()).then(() => {throw reason })); };
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/105517.html
摘要:就稱(chēng)為部署了遍歷器接口。是一個(gè)函數(shù),調(diào)用它會(huì)生成一個(gè)遍歷器對(duì)象。它的屬性,也是一個(gè)遍歷器對(duì)象生成函數(shù),執(zhí)行后返回它自己。返回遍歷器對(duì)象。下面是一個(gè)無(wú)限運(yùn)行的遍歷器對(duì)象的例子。 『ES6知識(shí)點(diǎn)總結(jié)』遍歷器iterator本文內(nèi)容如下: 1 具有iterator接口的數(shù)據(jù)結(jié)構(gòu) 2 遍歷器過(guò)程 3 遍歷器作用: 4 模擬next()方法 5 使用while循環(huán) 6 TypeScript的寫(xiě)法...
摘要:它是語(yǔ)言的第七種數(shù)據(jù)類(lèi)型,前六種是布爾值字符串?dāng)?shù)值對(duì)象。在中,根據(jù)屬性名來(lái)進(jìn)行判斷。,是一個(gè)布爾值,表示該對(duì)象使用時(shí),是否可以展開(kāi)。等同于,指向該對(duì)象的默認(rèn)遍歷器方法,即該對(duì)象進(jìn)行循環(huán)時(shí),會(huì)調(diào)用這個(gè)方法,返回該對(duì)象的默認(rèn)遍歷器。 本文字?jǐn)?shù):3000+,閱讀時(shí)間6分鐘。 如果有理解不到位的地方,歡迎大家糾錯(cuò)。如果覺(jué)得還可以,希望大家可以點(diǎn)個(gè)贊。 謝謝大家。 目錄 一、Symbol是什么...
摘要:箭頭函數(shù)本文字符數(shù),閱讀時(shí)間約分鐘左右。箭頭函數(shù)等于說(shuō),只保留了函數(shù)的參數(shù)和返回。箭頭函數(shù)體內(nèi)的,繼承的是外層代碼塊的。所以,不用用箭頭函數(shù)聲明對(duì)象的方法。不可以使用命令因此箭頭函數(shù)不能用作函數(shù)。 【01】ES6箭頭函數(shù) 本文字符數(shù)4300+,閱讀時(shí)間約8分鐘左右。 【01】箭頭函數(shù) 等于說(shuō),只保留了函數(shù)的參數(shù)和返回。省略function和return。 寫(xiě)法: (形參) => {st...
摘要:命令用于規(guī)定本模塊的對(duì)外接口??崭衲K名字符串。其他模塊加載該模塊時(shí),命令可以為該匿名函數(shù)指定任意名字。寫(xiě)法函數(shù)聲明命令用在非匿名函數(shù)前,也是可以的。加載的時(shí)候,視同匿名函數(shù)加載。 本文字符數(shù)8200+,閱讀時(shí)間約16分鐘。 『ES6知識(shí)點(diǎn)總結(jié)』模塊Module 第一節(jié):Module基本概念 【01】過(guò)去使用CommonJS和AMD,前者用于服務(wù)器,后者用于瀏覽器。 Module可以取...
摘要:返回一個(gè)布爾值,表示該值是否為的成員。清除所有成員,沒(méi)有返回值。返回的都是遍歷器對(duì)象。結(jié)構(gòu)的實(shí)例的方法,用于對(duì)每個(gè)成員執(zhí)行某種操作,沒(méi)有返回值。這個(gè)特點(diǎn)意味著,無(wú)法引用的成員,因此是不可遍歷的。數(shù)組成員是一個(gè)或多個(gè)表示鍵值對(duì)的一維數(shù)組。 本文字?jǐn)?shù):4700+,閱讀時(shí)間約10分鐘。 如果有理解不到位的地方,歡迎大家糾錯(cuò)。 一、Set 【01】Set是一種數(shù)據(jù)結(jié)構(gòu)。類(lèi)似于數(shù)組,但是成員的值...
閱讀 6940·2021-09-22 15:08
閱讀 1935·2021-08-24 10:03
閱讀 2450·2021-08-20 09:36
閱讀 1331·2020-12-03 17:22
閱讀 2483·2019-08-30 15:55
閱讀 914·2019-08-29 16:13
閱讀 3063·2019-08-29 12:41
閱讀 3260·2019-08-26 12:12