摘要:是一種異步編程的解決方案相比傳統(tǒng)回調(diào)函數(shù)更合理立即執(zhí)行性立即執(zhí)行返回成功后執(zhí)行控制臺(tái)輸出立即執(zhí)行后執(zhí)行返回成功對(duì)象表示未來(lái)發(fā)生的事件在創(chuàng)建時(shí)作為參數(shù)傳入的函數(shù)是會(huì)被立即執(zhí)行的只是其中執(zhí)行的代碼可以是異步代碼有些人會(huì)認(rèn)為當(dāng)對(duì)象調(diào)用方法時(shí)接受的
Promise是一種異步編程的解決方案,相比傳統(tǒng)回調(diào)函數(shù)更合理.
1.Promise立即執(zhí)行性
let p = new Promise((resolve, reject) => { console.log("立即執(zhí)行!"); resolve("返回成功!") }); console.log("promise后執(zhí)行!"); p.then(value => { console.log(value) });
控制臺(tái)輸出:
"立即執(zhí)行!" "promise后執(zhí)行!" "返回成功!"
Promise對(duì)象表示未來(lái)發(fā)生的事件,在創(chuàng)建promise時(shí),作為promise參數(shù)傳入的函數(shù)是會(huì)被立即執(zhí)行的,只是其中執(zhí)行的代碼可以是異步代碼.有些人會(huì)認(rèn)為,當(dāng)promise對(duì)象調(diào)用then方法時(shí),promise接受的函數(shù)才會(huì)執(zhí)行,這是錯(cuò)誤的.所以,代碼中立即執(zhí)行!先于promise后執(zhí)行!輸出.
2.Promise的三種狀態(tài).
let p1 = new Promise((reslove, reject) => { reslove(1); }); let p2 = new Promise((reslove, reject) => { setTimeout(() => { reslove(2); }, 500); }); let p3 = new Promise((reslove, reject) => { setTimeout(() => { reject(3); }, 500); }); console.log(p1); console.log(p2); console.log(p3); setTimeout(() => { console.log(p2); }, 1000); setTimeout(() => { console.log(p3); }, 1000); p1.then(value => { console.log(value); }); p2.then(value => { console.log(value); }); p3.catch(err => { console.log(err); });
控制臺(tái)輸出:
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內(nèi)部實(shí)現(xiàn)是一個(gè)狀態(tài)機(jī).Promise有三種狀態(tài): pending,resolved,rejected.當(dāng)Promise剛創(chuàng)建完成時(shí),處于pending狀態(tài);當(dāng)Promise中的函數(shù)參數(shù)執(zhí)行了resolve后,Promise由pending狀態(tài)變成resloved狀態(tài);如果Promise的函數(shù)參數(shù)中執(zhí)行的是reject方法,那么Promise會(huì)有pending狀態(tài)變成rejected狀態(tài).
3.Promise狀態(tài)不可逆性.
let p1 = new Promise((reslove, reject) => { reslove("成功1!"); reslove("成功2!"); }); let p2 = new Promise((reslove, reject) => { reslove("成功!"); reject("失敗!"); }); p1.then(value => { console.log(value); }); p2.then(value => { console.log(value); });
控制臺(tái)輸出:
"成功1!" "成功!"
Promise的狀態(tài)一旦變成resolved或rejected時(shí),Promise的狀態(tài)和值就固定下來(lái)了,無(wú)論后續(xù)再怎么調(diào)用reslove或是reject方法,都不能改變它的狀態(tài)和值.所以,p1中reslove("成功2!")并不能將p1的值更改為成功2!,p2中reject("失敗!")也不能將p2的狀態(tài)由resolved改變?yōu)閞ejected.
4.鏈?zhǔn)秸{(diào)用.
let p = new Promise((resolve, reject) => { resolve(1); }); p.then(value => { console.log(value); return value * 2; }).then(value => { console.log(value); }).then(value => { console.log(value); return Promise.resolve("resolve"); }).then(value => { console.log(value); return Promise.reject("reject"); }).then(value => { console.log(`resolve: ${value}`); }, err => { console.log(`reject: ${err}`); })
控制臺(tái)輸出:
1 2 undefined "resolve" "reject: reject"
Promise對(duì)象的then方法返回一個(gè)新的Promise對(duì)象,所以可以通過(guò)鏈?zhǔn)秸{(diào)用then方法.then方法接受兩個(gè)函數(shù)作為參數(shù),第一個(gè)參數(shù)是Promise執(zhí)行成功時(shí)的回調(diào),第二個(gè)參數(shù)是Promise執(zhí)行失敗時(shí)的回調(diào).兩個(gè)函數(shù)只會(huì)有一個(gè)被調(diào)用,函數(shù)返回值將用作創(chuàng)建then返回的Promise對(duì)象.這兩個(gè)參數(shù)的返回值可以是下面三種情況的一種:
①:return一個(gè)同步的值,或者undefined(當(dāng)沒(méi)有返回一個(gè)有效值時(shí),默認(rèn)返回undefined),then方法將返回一個(gè)resloved狀態(tài)的Promise對(duì)象,Promise對(duì)象的值就是這個(gè)返回值. ②:return另一個(gè)Promise,then方法將根據(jù)這個(gè)Promise的狀態(tài)和值創(chuàng)建一個(gè)新的Promise對(duì)象返回. ③:throw一個(gè)同步異常,then方法將返回一個(gè)rejected狀態(tài)的Promise,值是該異常.
根據(jù)以上分析,代碼中的第一個(gè)then會(huì)返回一個(gè)值為2(1 * 2),狀態(tài)為resolved的Promise對(duì)象,于第二個(gè)then輸出的值為2.第二個(gè)then中沒(méi)有返回值,因此將返回默認(rèn)的undefined,于是在第三個(gè)then中輸出的undefined.第三個(gè)then和第四個(gè)then中分別返回一個(gè)狀態(tài)是resloved的Promise和一個(gè)狀態(tài)是rejected的Promise,依次由第四個(gè)then中的成功回調(diào)函數(shù)和第五個(gè)then中的失敗回調(diào)函數(shù)處理.
5.Promise then()回調(diào)異步性.
let p = new Promise((resolve, reject) => { resolve("成功!"); }); p.then(value => { console.log(value); }); console.log("誰(shuí)先執(zhí)行?")
控制臺(tái)輸出:
"誰(shuí)先執(zhí)行?" "成功!"
Promise接受的函數(shù)參數(shù)是同步執(zhí)行的,但是then方法中的回調(diào)函數(shù)則是異步的,因此,成功!會(huì)在后面輸出.
6.Promise中的異常.
let p1 = new Promise((resolve, reject) => { foo.bar(); resolve(1); }); p1.then(value => { console.log(`p1 then value: ${value}`); }, err => { console.log(`p1 then err: ${err}`); }).then(value => { console.log(`p1 then then value: ${value}`); }, err => { console.log(`p1 then then err: ${err}`); }); let p2 = new Promise((resolve, reject) => { resolve(2); }); p2.then(value => { console.log(`p2 then value: ${value}`); foo.bar(); }, err => { console.log(`p2 then err: ${err}`); }).then(value => { console.log(`p2 then then value: ${value}`); }, err => { console.log(`p2 then then err: ${err}`); return 1; }).then(value => { console.log(`p2 then then then value: ${value}`); }, err => { console.log(`p2 then then then err: ${err}`); });
控制臺(tái)輸出:
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參數(shù)中的第二個(gè)回調(diào)函數(shù)(Promise執(zhí)行失敗的回調(diào))處理,異常信息將作為Promise的值.異常一旦得到處理,then返回后續(xù)的Promise對(duì)象將恢復(fù)正常,并會(huì)被Promise執(zhí)行成功的回調(diào)函數(shù)處理.另外,需要注意p1,p2多級(jí)then的回調(diào)函數(shù)是交替執(zhí)行的,這正是由Promise then回調(diào)的異步性決定的.
7.Promise.reslove().
let p1 = Promise.resolve(1); let p2 = Promise.resolve(p1); let p3 = new Promise((resolve, reject) => { resolve(1); }); let p4 = new Promise((resolve, reject) => { resolve(p1); }); console.log(p1 === p2); console.log(p1 === p3); console.log(p1 === p4); console.log(p3 === p4); p4.then(value => { console.log(`p4=${value}`) }); p2.then(value => { console.log(`p2=${value}`) }); p1.then(value => { console.log(`p1=${value}`) });
控制臺(tái)輸出:
true false false false p2=1 p1=1 p4=1
Promise.resolve(...) 可以接受一個(gè)值或者是一個(gè)Promise對(duì)象作為參數(shù).當(dāng)參數(shù)是普通值時(shí),它返回一個(gè)resolved狀態(tài)的Promise對(duì)象,對(duì)象的值就是這個(gè)參數(shù);當(dāng)參數(shù)是一個(gè)Promise對(duì)象時(shí),它直接返回這個(gè)Promise參數(shù).所以p1===p2.但通過(guò)new創(chuàng)建的Promise對(duì)象都是一個(gè)新的對(duì)象,所以后面三個(gè)比較結(jié)果都是false.另外,為什么p4的then最先調(diào)用,但是在控制臺(tái)上是最后輸出結(jié)果的呢?因?yàn)閜4中resolve接受的參數(shù)是一個(gè)Promise對(duì)象p1,reslove會(huì)對(duì)p1進(jìn)行解析,獲取p1的狀態(tài)和值,但是這個(gè)過(guò)程是異步的.
8.resolve v reject.
let p1 = new Promise((resolve, reject) => { resolve(Promise.resolve("resolve")); }); let p2 = new Promise((resolve, reject) => { resolve(Promise.reject("reject")); }); let p3 = new Promise((resolve, reject) => { reject(Promise.resolve("resolve")); }); p1.then(value => { console.log(`p1 fulfilled: ${value}`); }, err => { console.log(`p1 rejected: ${err}`); }); p2.then(value => { console.log(`p2 fulfilled: ${value}`); }, err => { console.log(`p2 rejected: ${err}`); }); p3.then(value => { console.log(`p3 fulfilled: ${value}`); }, err => { console.log(`p3 rejected: ${err}`); });
控制臺(tái)輸出:
p3 rejected: [object Promise] p1 fulfilled: resolve p2 rejected: reject
Promise回調(diào)函數(shù)中的第一個(gè)參數(shù)resolve,會(huì)對(duì)Promise執(zhí)行解析,即resolve的參數(shù)是Promise對(duì)象時(shí),resolve會(huì)解析獲取這個(gè)Promise對(duì)象的狀態(tài)和值,但這個(gè)過(guò)程是異步的.p1解析后,獲取到Promise對(duì)象的狀態(tài)是resolved,因此第一個(gè)回調(diào)被執(zhí)行也就是獲取value的回調(diào);p2解析后,獲取到Promise對(duì)象的狀態(tài)rejected,因此rejected回調(diào)執(zhí)行.但Promise回調(diào)函數(shù)中的第二個(gè)參數(shù)reject不具備解析能力,reject的參數(shù)會(huì)直接傳遞給then方法中的rejected回調(diào),因此,即使p3 reject接受了一個(gè)resolved狀態(tài)的Promise,then方法中調(diào)用的依然是rejected,并且參數(shù)就是reject接受到的Promise對(duì)象.
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/84427.html
摘要:則是把類似的異步處理對(duì)象和處理規(guī)則進(jìn)行規(guī)范化,并按照采用統(tǒng)一的接口來(lái)編寫,而采取規(guī)定方法之外的寫法都會(huì)出錯(cuò)。這個(gè)對(duì)象有一個(gè)方法,指定回調(diào)函數(shù),用于在異步操作執(zhí)行完后執(zhí)行回調(diào)函數(shù)處理。到目前為止,已經(jīng)學(xué)習(xí)了創(chuàng)建對(duì)象和用,方法來(lái)注冊(cè)回調(diào)函數(shù)。 Promise 本文從js的異步處理出發(fā),引入Promise的概念,并且介紹Promise對(duì)象以及其API方法。 js里的異步處理 可以參考這篇文章...
摘要:就算改變已經(jīng)發(fā)生了,你再對(duì)對(duì)象添加回調(diào)函數(shù),也會(huì)立即得到這個(gè)結(jié)果。有了對(duì)象,就可以將異步操作以同步操作的流程表達(dá)出來(lái),避免了層層嵌套的回調(diào)函數(shù)。但是在這里,會(huì)得到這樣的結(jié)果關(guān)于是用于指定發(fā)生錯(cuò)誤時(shí)的回調(diào)函數(shù)。 看了很多關(guān)于promise的文章,此篇文章做以總結(jié)。由于Javascript是一種單線程的語(yǔ)言,所有的代碼必須按照所謂的自上而下的順序來(lái)執(zhí)行。本特性帶來(lái)的問(wèn)題就是,一些將來(lái)的、未...
摘要:關(guān)于的個(gè)提示正如同事所說(shuō)的那樣,在工作中表現(xiàn)優(yōu)異。這篇文章會(huì)給你一些如何改善與之間關(guān)系的建議。但是對(duì)于一個(gè)初學(xué)者來(lái)說(shuō),可能就不會(huì)了。在中不論你使用或者都會(huì)創(chuàng)建一個(gè)新的。這個(gè)是剛剛鏈?zhǔn)秸{(diào)用的和剛剛加上的的組合。 關(guān)于 Promise 的 9 個(gè)提示 正如同事所說(shuō)的那樣,Promise 在工作中表現(xiàn)優(yōu)異。 showImg(https://segmentfault.com/img/remot...
摘要:秒鐘后調(diào)用函數(shù)觀察上述代碼執(zhí)行,在的控制臺(tái)輸出可以看到就是典型的異步操作統(tǒng)一執(zhí)行邏輯,不關(guān)心如何處理結(jié)果,然后,根據(jù)結(jié)果是成功還是失敗,在將來(lái)的某個(gè)時(shí)候調(diào)用函數(shù)或函數(shù)。 Promise的學(xué)習(xí)和拓展 以前開(kāi)發(fā)的時(shí)候偶爾會(huì)在請(qǐng)求中,或者其他場(chǎng)景中用到promise,只知道它是什么(鏈?zhǔn)秸{(diào)用,用于請(qǐng)求的后返回值得操作之類的),大概怎么用,卻沒(méi)有深入了解。 起因:(在參考了廖雪峰的prom...
摘要:執(zhí)行,輸出,宏任務(wù)執(zhí)行結(jié)束。到此為止,第一輪事件循環(huán)結(jié)束。參考入門阮一峰系列之我們來(lái)聊聊一道關(guān)于應(yīng)用的面試題阿里前端測(cè)試題關(guān)于中函數(shù)的理解與應(yīng)用這一次,徹底弄懂執(zhí)行機(jī)制一個(gè)面試題原生的所有方法介紹附一道應(yīng)用場(chǎng)景題目異步流程控制 說(shuō)明 最近在復(fù)習(xí) Promise 的知識(shí),所以就做了一些題,這里挑出幾道題,大家一起看看吧。 題目一 const promise = new Promise((...
摘要:反之,操作失敗,對(duì)象由狀態(tài)轉(zhuǎn)換為狀態(tài),此時(shí)回調(diào)函數(shù)會(huì)執(zhí)行方法。這里需要注意的是,雖然在之后便執(zhí)行了方法,但是并不是意味著往后的對(duì)象不執(zhí)行了,其他的還是對(duì)象還是要執(zhí)行的,只是不會(huì)再調(diào)用函數(shù)。 在 掘金上看見(jiàn)一篇寫promise的文章,感覺(jué)作者寫的很棒,文章鏈接在這:八段代碼徹底掌握 Promise ??赐曛蟾杏X(jué)學(xué)到了很多,所以又重新把JavaScript Promise迷你書(中文版)...
閱讀 2784·2021-10-11 11:08
閱讀 1503·2021-09-30 09:48
閱讀 1062·2021-09-22 15:29
閱讀 1050·2019-08-30 15:54
閱讀 990·2019-08-29 15:19
閱讀 542·2019-08-29 13:12
閱讀 3176·2019-08-26 13:53
閱讀 979·2019-08-26 13:28