摘要:是一種異步編程的解決方案相比傳統回調函數更合理立即執行性立即執行返回成功后執行控制臺輸出立即執行后執行返回成功對象表示未來發生的事件在創建時作為參數傳入的函數是會被立即執行的只是其中執行的代碼可以是異步代碼有些人會認為當對象調用方法時接受的
Promise是一種異步編程的解決方案,相比傳統回調函數更合理.
1.Promise立即執行性
let p = new Promise((resolve, reject) => { console.log("立即執行!"); resolve("返回成功!") }); console.log("promise后執行!"); p.then(value => { console.log(value) });
控制臺輸出:
"立即執行!" "promise后執行!" "返回成功!"
Promise對象表示未來發生的事件,在創建promise時,作為promise參數傳入的函數是會被立即執行的,只是其中執行的代碼可以是異步代碼.有些人會認為,當promise對象調用then方法時,promise接受的函數才會執行,這是錯誤的.所以,代碼中立即執行!先于promise后執行!輸出.
2.Promise的三種狀態.
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); });
控制臺輸出:
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狀態變成resloved狀態;如果Promise的函數參數中執行的是reject方法,那么Promise會有pending狀態變成rejected狀態.
3.Promise狀態不可逆性.
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); });
控制臺輸出:
"成功1!" "成功!"
Promise的狀態一旦變成resolved或rejected時,Promise的狀態和值就固定下來了,無論后續再怎么調用reslove或是reject方法,都不能改變它的狀態和值.所以,p1中reslove("成功2!")并不能將p1的值更改為成功2!,p2中reject("失敗!")也不能將p2的狀態由resolved改變為rejected.
4.鏈式調用.
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}`); })
控制臺輸出:
1 2 undefined "resolve" "reject: reject"
Promise對象的then方法返回一個新的Promise對象,所以可以通過鏈式調用then方法.then方法接受兩個函數作為參數,第一個參數是Promise執行成功時的回調,第二個參數是Promise執行失敗時的回調.兩個函數只會有一個被調用,函數返回值將用作創建then返回的Promise對象.這兩個參數的返回值可以是下面三種情況的一種:
①:return一個同步的值,或者undefined(當沒有返回一個有效值時,默認返回undefined),then方法將返回一個resloved狀態的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中分別返回一個狀態是resloved的Promise和一個狀態是rejected的Promise,依次由第四個then中的成功回調函數和第五個then中的失敗回調函數處理.
5.Promise then()回調異步性.
let p = new Promise((resolve, reject) => { resolve("成功!"); }); p.then(value => { console.log(value); }); console.log("誰先執行?")
控制臺輸出:
"誰先執行?" "成功!"
Promise接受的函數參數是同步執行的,但是then方法中的回調函數則是異步的,因此,成功!會在后面輸出.
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}`); });
控制臺輸出:
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.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}`) });
控制臺輸出:
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,reslove會對p1進行解析,獲取p1的狀態和值,但是這個過程是異步的.
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}`); });
控制臺輸出:
p3 rejected: [object Promise] p1 fulfilled: resolve p2 rejected: reject
Promise回調函數中的第一個參數resolve,會對Promise執行解析,即resolve的參數是Promise對象時,resolve會解析獲取這個Promise對象的狀態和值,但這個過程是異步的.p1解析后,獲取到Promise對象的狀態是resolved,因此第一個回調被執行也就是獲取value的回調;p2解析后,獲取到Promise對象的狀態rejected,因此rejected回調執行.但Promise回調函數中的第二個參數reject不具備解析能力,reject的參數會直接傳遞給then方法中的rejected回調,因此,即使p3 reject接受了一個resolved狀態的Promise,then方法中調用的依然是rejected,并且參數就是reject接受到的Promise對象.
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/84427.html
摘要:則是把類似的異步處理對象和處理規則進行規范化,并按照采用統一的接口來編寫,而采取規定方法之外的寫法都會出錯。這個對象有一個方法,指定回調函數,用于在異步操作執行完后執行回調函數處理。到目前為止,已經學習了創建對象和用,方法來注冊回調函數。 Promise 本文從js的異步處理出發,引入Promise的概念,并且介紹Promise對象以及其API方法。 js里的異步處理 可以參考這篇文章...
摘要:就算改變已經發生了,你再對對象添加回調函數,也會立即得到這個結果。有了對象,就可以將異步操作以同步操作的流程表達出來,避免了層層嵌套的回調函數。但是在這里,會得到這樣的結果關于是用于指定發生錯誤時的回調函數。 看了很多關于promise的文章,此篇文章做以總結。由于Javascript是一種單線程的語言,所有的代碼必須按照所謂的自上而下的順序來執行。本特性帶來的問題就是,一些將來的、未...
摘要:關于的個提示正如同事所說的那樣,在工作中表現優異。這篇文章會給你一些如何改善與之間關系的建議。但是對于一個初學者來說,可能就不會了。在中不論你使用或者都會創建一個新的。這個是剛剛鏈式調用的和剛剛加上的的組合。 關于 Promise 的 9 個提示 正如同事所說的那樣,Promise 在工作中表現優異。 showImg(https://segmentfault.com/img/remot...
摘要:秒鐘后調用函數觀察上述代碼執行,在的控制臺輸出可以看到就是典型的異步操作統一執行邏輯,不關心如何處理結果,然后,根據結果是成功還是失敗,在將來的某個時候調用函數或函數。 Promise的學習和拓展 以前開發的時候偶爾會在請求中,或者其他場景中用到promise,只知道它是什么(鏈式調用,用于請求的后返回值得操作之類的),大概怎么用,卻沒有深入了解。 起因:(在參考了廖雪峰的prom...
摘要:執行,輸出,宏任務執行結束。到此為止,第一輪事件循環結束。參考入門阮一峰系列之我們來聊聊一道關于應用的面試題阿里前端測試題關于中函數的理解與應用這一次,徹底弄懂執行機制一個面試題原生的所有方法介紹附一道應用場景題目異步流程控制 說明 最近在復習 Promise 的知識,所以就做了一些題,這里挑出幾道題,大家一起看看吧。 題目一 const promise = new Promise((...
閱讀 2771·2021-10-11 11:08
閱讀 1489·2021-09-30 09:48
閱讀 1049·2021-09-22 15:29
閱讀 1037·2019-08-30 15:54
閱讀 976·2019-08-29 15:19
閱讀 527·2019-08-29 13:12
閱讀 3161·2019-08-26 13:53
閱讀 957·2019-08-26 13:28