摘要:初識(shí)對(duì)象是一個(gè)構(gòu)造函數(shù),其接受一個(gè)函數(shù)作為參數(shù),為這個(gè)函數(shù)的參數(shù),函數(shù)內(nèi)部一般為異步執(zhí)行的代碼,作為異步執(zhí)行完成之后成功的回調(diào),作為異步執(zhí)行拋錯(cuò)的回調(diào)。構(gòu)造函數(shù)可以理解為執(zhí)行異步的過程,其和為執(zhí)行異步調(diào)用結(jié)果的回調(diào)函數(shù)。
初識(shí)Promise
Promise對(duì)象是一個(gè)構(gòu)造函數(shù),其接受一個(gè)函數(shù)作為參數(shù),resolve、reject為這個(gè)函數(shù)的參數(shù),函數(shù)內(nèi)部一般為異步執(zhí)行的代碼,resolve作為異步執(zhí)行完成之后成功的回調(diào),reject作為異步執(zhí)行拋錯(cuò)的回調(diào)。Promise構(gòu)造函數(shù)可以理解為執(zhí)行異步的過程,其resolve和reject為執(zhí)行異步調(diào)用結(jié)果的回調(diào)函數(shù)。
// 代碼1 var p = new Promise((resolve, reject) => { // 執(zhí)行一系列的異步執(zhí)行 // some codes... if (true) { resolve("異步執(zhí)行成功"); } else { reject("異步執(zhí)行拋錯(cuò)"); } }); // fulfilled: 異步執(zhí)行成功 ; 非fulfilled: 異步執(zhí)行拋錯(cuò)Promise的異步處理 then和catch的使用
Promise構(gòu)造函數(shù)返回一個(gè)異步執(zhí)行之后的promise對(duì)象,該對(duì)象對(duì)異步的結(jié)果進(jìn)一步處理。
// 代碼2 p .then((res) => { // try catch 手動(dòng)拋錯(cuò) try { // console.log("異步返回成功狀態(tài)"); throw Error("錯(cuò)誤代碼"); } catch(e) { console.log("執(zhí)行catch"); return Promise.reject(e); } }) .catch((res) => { console.log(res); // 輸出上一個(gè) then 中 catch 的 e return "這里由錯(cuò)誤信息過去的數(shù)據(jù)"; }) .then((res) => { console.log(res); // 若上一個(gè)catch執(zhí)行,輸出:這里由錯(cuò)誤信息過去的數(shù)據(jù) })
以上代碼執(zhí)行結(jié)果:
# 結(jié)果1 執(zhí)行catch Error: 錯(cuò)誤代碼 at p.then (**/promise.js:77:10) at process._tickCallback (internal/process/next_tick.js:109:7) at Module.runMain (module.js:607:11) at run (bootstrap_node.js:423:7) at startup (bootstrap_node.js:147:9) at bootstrap_node.js:538:3 這里由錯(cuò)誤信息過去的數(shù)據(jù)promise對(duì)象的鏈?zhǔn)秸{(diào)用
由代碼2可以看出,promise對(duì)象狀態(tài)為resolve的時(shí)候,執(zhí)行then方法,而且在不拋錯(cuò)情況下會(huì)持續(xù)執(zhí)行鏈?zhǔn)秸{(diào)用的then方法,若then方法拋出異?;蛘邟伋龇祷?b>Promise.reject()方法,會(huì)轉(zhuǎn)到執(zhí)行catch方法,若catch方法返回的不是Promise.reject()方法或者不拋出異常,則所有使用return返回的數(shù)據(jù)都會(huì)作為參數(shù)傳給下一個(gè)then函數(shù)參數(shù)的參數(shù),即代碼2中的最后一個(gè)then方法指定函數(shù)參數(shù)的res是上一個(gè)catch所return的數(shù)據(jù)。
var p = new Promise((resolve, reject) => { resolve("ok"); }); p.then((msg) => { console.log(msg); return Promise.reject("then01拋錯(cuò)"); }).catch((errMsg) => { console.warn(errMsg); }).then(() => { console.log("then02再執(zhí)行"); }).then(() => { console.log("then03再執(zhí)行"); return Promise.reject("then03拋錯(cuò)"); }).catch((errMsg) => { console.warn(errMsg); return "catch02 return 給下一個(gè)then指定方法的值"; }).then((msg) => { console.log(msg); });
運(yùn)行結(jié)果如下:
這是因?yàn)?b>then方法和catch方法返回的都是一個(gè)promise對(duì)象。then方法指定的回調(diào)函數(shù)拋出錯(cuò)誤會(huì)被下一個(gè)catch方法捕獲,多個(gè)then方法執(zhí)行也是如此。catch方法會(huì)捕獲上一個(gè)catch方法(如果有的話)之后拋錯(cuò)的錯(cuò)誤。
Promise狀態(tài)換言之,無論是then方法還是catch方法,返回的都是一個(gè)promise對(duì)象,其狀態(tài)取決于上一個(gè)方法指定的函數(shù)是否順利執(zhí)行或者沒有返回Promise.reject()。
一旦Promise的狀態(tài)變?yōu)閞esolved或者rejected,就會(huì)永久保持該狀態(tài),不會(huì)再變。
var p = new Promise((resolve, reject) => { resolve("ok"); throw new Error("wrong"); }); p.then((msg) => { console.log(msg); }).catch((errMsg) => { console.warn(errMsg); }); // ok
在Promise的參數(shù)函數(shù)中,由于先斷定了resolved狀態(tài),所以在之后只會(huì)執(zhí)行then函數(shù),后面拋出的錯(cuò)誤會(huì)等于沒拋出來。
另外,“事件循環(huán)”會(huì)對(duì)拋出的結(jié)果有影響。
var p = new Promise((resolve, reject) => { resolve("ok"); setTimeout(() => { throw new Error("wrong"); }, 0); }); p.then((msg) => { console.log(msg); }).catch((errMsg) => { console.warn(errMsg); }); // ok // 瀏覽器拋出的錯(cuò)誤 // index.js:4 Uncaught Error: wrong // at setTimeout (index.js:4) // setTimeout @ index.js:4
在本輪“事件循環(huán)”中,promise對(duì)象p先執(zhí)行,所以構(gòu)造函數(shù)Promise的指定函數(shù)先輸出‘ok’;在進(jìn)入到下一次的“事件循環(huán)”的時(shí)候,由于Promise函數(shù)體已經(jīng)執(zhí)行完畢,故后面拋出的錯(cuò)誤是在Promise函數(shù)體外拋出的,Promise函數(shù)體無法捕獲到這個(gè)錯(cuò)誤。
Promise.resolve()Promise.resolve()接受一個(gè)參數(shù),其返回一個(gè)promise對(duì)象的狀態(tài)會(huì)因?yàn)閭魅氲膮?shù)的不同而不同。
參數(shù)分別以下幾種情況:空
返回一個(gè)狀態(tài)為resolved的promise對(duì)象,也就是下一步會(huì)執(zhí)行then方法。
var p = Promise.resolve(); p.then((res) => { console.log("then"); }).catch((res) => { console.log("catch"); }); // then
thenable對(duì)象
var thenable = { then: function (resolve, reject) { console.log("立即執(zhí)行thenable的then的方法" + Date.now()); resolve("斷定之后的信息"); } } var p = Promise.resolve(thenable); p.then((res) => { console.log(res); }); // 立即執(zhí)行thenable的then的方法1494485393447 // 斷定之后的信息 // 相當(dāng)于 var p = new Promise(function (resolve, reject) { console.log("立即執(zhí)行thenable的then的方法" + Date.now()); resolve("斷定之后的信息"); }); p.then((res) => { console.log(res); }); // 立即執(zhí)行thenable的then的方法1494485454503 // 斷定之后的信息
thenable對(duì)象作為參數(shù),在執(zhí)行Promise.resolve(thenable)方法的時(shí)候,會(huì)立即執(zhí)行thenable對(duì)象中的then方法,并且其返回的Promise對(duì)象的狀態(tài)取決于thenable對(duì)象的then方法執(zhí)行的是resolve()還是reject()。這種情況下,就相當(dāng)于Promise構(gòu)造函數(shù)以thenable對(duì)象的then方法作為參數(shù),實(shí)例化一個(gè)Promise實(shí)例。
一個(gè)非Promise對(duì)象,且不含有then方法的對(duì)象------非thenable對(duì)象
var p = Promise.resolve({ a: 1 }); p.then((res) => { console.log(res); }); // { a: 1 } var p01 = Promise.resolve("Hello Promise!"); p01.then((res) => { console.log(res); }); // Hello Promise!
這種情況下,Promise.resolve()的狀態(tài)為resolved,其接收的參數(shù)會(huì)作為then方法指定函數(shù)的參數(shù)。
Promise對(duì)象
var p01 = new Promise((resolve, reject) => { reject("Throw some error! Come on! You bite me."); }); var p = Promise.resolve(p01); p.then((res) => { console.log("這是then方法"); }).catch((errMsg) => { console.log(errMsg); }); // Throw some error! Come on! You bite me.
傳入的是一個(gè)Promise對(duì)象,Promise.resolve()返回的對(duì)象的狀態(tài)就是傳入的Promise對(duì)象的狀態(tài)。
Promise.reject()Promise.reject(reason)方法同樣返回一個(gè)狀態(tài)為rejected的Promise對(duì)象實(shí)例。值得注意的是,參數(shù)reason(Promise狀態(tài)rejected的原因)不論是什么值,都會(huì)傳給返回的Promise對(duì)象的catch方法指定的函數(shù)作為參數(shù)。
var p = Promise.reject("Throw some error! Come on! You bite me."); p.then((res) => { console.log("這是then方法"); }).catch((errMsg) => { console.log(errMsg); }); // Throw some error! Come on! You bite me.promise對(duì)象的使用場景——圖片加載
var imgPromise = function (url) { return new Promise((resolve, reject) => { var img = new Image(); img.src = url; img.onload = resolve; img.onerror = reject; }); } imgPromise("http://imgurl") .then((res) => { console.log("圖片加載完成"); }) .catch((res) => { console.log("圖片加載失敗"); }):
參考文章
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/82808.html
摘要:上代碼異步執(zhí)行成功的構(gòu)造函數(shù)接收一個(gè)函數(shù)參數(shù),并傳入兩個(gè)參數(shù),分別表示異步操作執(zhí)行成功后的回調(diào)函數(shù)和異步操作執(zhí)行失敗后的回調(diào)函數(shù)。第一個(gè)回調(diào)函數(shù)是對(duì)象的狀態(tài)變?yōu)闀r(shí)調(diào)用,第二個(gè)回調(diào)函數(shù)是對(duì)象的狀態(tài)變?yōu)闀r(shí)調(diào)用。 這篇文章只解決三個(gè)問題。什么是promise? promise有什么用?promise怎么用? 1.什么是promise? 對(duì)于ES6來說,就是一個(gè)構(gòu)造函數(shù),可以用new Prom...
摘要:從最開始的到封裝后的都在試圖解決異步編程過程中的問題。為了讓編程更美好,我們就需要引入來降低異步編程的復(fù)雜性。異步編程入門的全稱是前端經(jīng)典面試題從輸入到頁面加載發(fā)生了什么這是一篇開發(fā)的科普類文章,涉及到優(yōu)化等多個(gè)方面。 TypeScript 入門教程 從 JavaScript 程序員的角度總結(jié)思考,循序漸進(jìn)的理解 TypeScript。 網(wǎng)絡(luò)基礎(chǔ)知識(shí)之 HTTP 協(xié)議 詳細(xì)介紹 HTT...
摘要:的翻譯文檔由的維護(hù)很多人說,阮老師已經(jīng)有一本關(guān)于的書了入門,覺得看看這本書就足夠了。前端的異步解決方案之和異步編程模式在前端開發(fā)過程中,顯得越來越重要。為了讓編程更美好,我們就需要引入來降低異步編程的復(fù)雜性。 JavaScript Promise 迷你書(中文版) 超詳細(xì)介紹promise的gitbook,看完再不會(huì)promise...... 本書的目的是以目前還在制定中的ECMASc...
摘要:今天對(duì)于處理異步調(diào)用已經(jīng)有了很多成熟的方案,在我看來這些方案都無外乎在解決一個(gè)問題如何能看似順序地傳遞異步調(diào)用的結(jié)果,本文要說的就是原生提供的一個(gè)解決方案。在對(duì)進(jìn)行敘述之前,依舊引用阮大的入門一書中的章節(jié)便于大家更嚴(yán)謹(jǐn)和全面的學(xué)習(xí)和參考。 異步回調(diào)的泥潭 異步回調(diào)是最直接的異步結(jié)果處理模式,將一個(gè)回調(diào)函數(shù)callback扔進(jìn)異步處理函數(shù)中,當(dāng)異步處理獲得結(jié)果之后再調(diào)用這個(gè)回調(diào)函數(shù)就可以...
摘要:源碼學(xué)習(xí)本篇為上一篇源碼學(xué)習(xí)的補(bǔ)充,主要是來介紹和方法。那個(gè)率先改變的實(shí)例的返回值,就傳遞給的回調(diào)函數(shù)?;窘榻B可見阮一峰老師的書籍。的狀態(tài)由決定,分成兩種情況。只有的狀態(tài)都變成,的狀態(tài)才會(huì)變成,此時(shí)的返回值組成一個(gè)數(shù)組,傳遞給的回調(diào)函數(shù)。 Promise源碼學(xué)習(xí)(2) 本篇為上一篇源碼學(xué)習(xí)(1)的補(bǔ)充,主要是來介紹Promise.all()和Promise.race()方法。閑話少敘...
閱讀 1886·2023-04-26 02:43
閱讀 3615·2021-11-11 16:54
閱讀 1494·2021-09-23 11:54
閱讀 1300·2021-09-23 11:22
閱讀 2519·2021-08-23 09:45
閱讀 1031·2019-08-30 15:54
閱讀 3200·2019-08-30 15:53
閱讀 3297·2019-08-30 15:53