摘要:初識對象是一個構造函數,其接受一個函數作為參數,為這個函數的參數,函數內部一般為異步執行的代碼,作為異步執行完成之后成功的回調,作為異步執行拋錯的回調。構造函數可以理解為執行異步的過程,其和為執行異步調用結果的回調函數。
初識Promise
Promise對象是一個構造函數,其接受一個函數作為參數,resolve、reject為這個函數的參數,函數內部一般為異步執行的代碼,resolve作為異步執行完成之后成功的回調,reject作為異步執行拋錯的回調。Promise構造函數可以理解為執行異步的過程,其resolve和reject為執行異步調用結果的回調函數。
// 代碼1 var p = new Promise((resolve, reject) => { // 執行一系列的異步執行 // some codes... if (true) { resolve("異步執行成功"); } else { reject("異步執行拋錯"); } }); // fulfilled: 異步執行成功 ; 非fulfilled: 異步執行拋錯Promise的異步處理 then和catch的使用
Promise構造函數返回一個異步執行之后的promise對象,該對象對異步的結果進一步處理。
// 代碼2 p .then((res) => { // try catch 手動拋錯 try { // console.log("異步返回成功狀態"); throw Error("錯誤代碼"); } catch(e) { console.log("執行catch"); return Promise.reject(e); } }) .catch((res) => { console.log(res); // 輸出上一個 then 中 catch 的 e return "這里由錯誤信息過去的數據"; }) .then((res) => { console.log(res); // 若上一個catch執行,輸出:這里由錯誤信息過去的數據 })
以上代碼執行結果:
# 結果1 執行catch Error: 錯誤代碼 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 這里由錯誤信息過去的數據promise對象的鏈式調用
由代碼2可以看出,promise對象狀態為resolve的時候,執行then方法,而且在不拋錯情況下會持續執行鏈式調用的then方法,若then方法拋出異常或者拋出返回Promise.reject()方法,會轉到執行catch方法,若catch方法返回的不是Promise.reject()方法或者不拋出異常,則所有使用return返回的數據都會作為參數傳給下一個then函數參數的參數,即代碼2中的最后一個then方法指定函數參數的res是上一個catch所return的數據。
var p = new Promise((resolve, reject) => { resolve("ok"); }); p.then((msg) => { console.log(msg); return Promise.reject("then01拋錯"); }).catch((errMsg) => { console.warn(errMsg); }).then(() => { console.log("then02再執行"); }).then(() => { console.log("then03再執行"); return Promise.reject("then03拋錯"); }).catch((errMsg) => { console.warn(errMsg); return "catch02 return 給下一個then指定方法的值"; }).then((msg) => { console.log(msg); });
運行結果如下:
這是因為then方法和catch方法返回的都是一個promise對象。then方法指定的回調函數拋出錯誤會被下一個catch方法捕獲,多個then方法執行也是如此。catch方法會捕獲上一個catch方法(如果有的話)之后拋錯的錯誤。
Promise狀態換言之,無論是then方法還是catch方法,返回的都是一個promise對象,其狀態取決于上一個方法指定的函數是否順利執行或者沒有返回Promise.reject()。
一旦Promise的狀態變為resolved或者rejected,就會永久保持該狀態,不會再變。
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的參數函數中,由于先斷定了resolved狀態,所以在之后只會執行then函數,后面拋出的錯誤會等于沒拋出來。
另外,“事件循環”會對拋出的結果有影響。
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 // 瀏覽器拋出的錯誤 // index.js:4 Uncaught Error: wrong // at setTimeout (index.js:4) // setTimeout @ index.js:4
在本輪“事件循環”中,promise對象p先執行,所以構造函數Promise的指定函數先輸出‘ok’;在進入到下一次的“事件循環”的時候,由于Promise函數體已經執行完畢,故后面拋出的錯誤是在Promise函數體外拋出的,Promise函數體無法捕獲到這個錯誤。
Promise.resolve()Promise.resolve()接受一個參數,其返回一個promise對象的狀態會因為傳入的參數的不同而不同。
參數分別以下幾種情況:空
返回一個狀態為resolved的promise對象,也就是下一步會執行then方法。
var p = Promise.resolve(); p.then((res) => { console.log("then"); }).catch((res) => { console.log("catch"); }); // then
thenable對象
var thenable = { then: function (resolve, reject) { console.log("立即執行thenable的then的方法" + Date.now()); resolve("斷定之后的信息"); } } var p = Promise.resolve(thenable); p.then((res) => { console.log(res); }); // 立即執行thenable的then的方法1494485393447 // 斷定之后的信息 // 相當于 var p = new Promise(function (resolve, reject) { console.log("立即執行thenable的then的方法" + Date.now()); resolve("斷定之后的信息"); }); p.then((res) => { console.log(res); }); // 立即執行thenable的then的方法1494485454503 // 斷定之后的信息
thenable對象作為參數,在執行Promise.resolve(thenable)方法的時候,會立即執行thenable對象中的then方法,并且其返回的Promise對象的狀態取決于thenable對象的then方法執行的是resolve()還是reject()。這種情況下,就相當于Promise構造函數以thenable對象的then方法作為參數,實例化一個Promise實例。
一個非Promise對象,且不含有then方法的對象------非thenable對象
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()的狀態為resolved,其接收的參數會作為then方法指定函數的參數。
Promise對象
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.
傳入的是一個Promise對象,Promise.resolve()返回的對象的狀態就是傳入的Promise對象的狀態。
Promise.reject()Promise.reject(reason)方法同樣返回一個狀態為rejected的Promise對象實例。值得注意的是,參數reason(Promise狀態rejected的原因)不論是什么值,都會傳給返回的Promise對象的catch方法指定的函數作為參數。
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對象的使用場景——圖片加載
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("圖片加載失敗"); }):
參考文章
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/82808.html
摘要:上代碼異步執行成功的構造函數接收一個函數參數,并傳入兩個參數,分別表示異步操作執行成功后的回調函數和異步操作執行失敗后的回調函數。第一個回調函數是對象的狀態變為時調用,第二個回調函數是對象的狀態變為時調用。 這篇文章只解決三個問題。什么是promise? promise有什么用?promise怎么用? 1.什么是promise? 對于ES6來說,就是一個構造函數,可以用new Prom...
摘要:從最開始的到封裝后的都在試圖解決異步編程過程中的問題。為了讓編程更美好,我們就需要引入來降低異步編程的復雜性。異步編程入門的全稱是前端經典面試題從輸入到頁面加載發生了什么這是一篇開發的科普類文章,涉及到優化等多個方面。 TypeScript 入門教程 從 JavaScript 程序員的角度總結思考,循序漸進的理解 TypeScript。 網絡基礎知識之 HTTP 協議 詳細介紹 HTT...
摘要:的翻譯文檔由的維護很多人說,阮老師已經有一本關于的書了入門,覺得看看這本書就足夠了。前端的異步解決方案之和異步編程模式在前端開發過程中,顯得越來越重要。為了讓編程更美好,我們就需要引入來降低異步編程的復雜性。 JavaScript Promise 迷你書(中文版) 超詳細介紹promise的gitbook,看完再不會promise...... 本書的目的是以目前還在制定中的ECMASc...
摘要:今天對于處理異步調用已經有了很多成熟的方案,在我看來這些方案都無外乎在解決一個問題如何能看似順序地傳遞異步調用的結果,本文要說的就是原生提供的一個解決方案。在對進行敘述之前,依舊引用阮大的入門一書中的章節便于大家更嚴謹和全面的學習和參考。 異步回調的泥潭 異步回調是最直接的異步結果處理模式,將一個回調函數callback扔進異步處理函數中,當異步處理獲得結果之后再調用這個回調函數就可以...
摘要:源碼學習本篇為上一篇源碼學習的補充,主要是來介紹和方法。那個率先改變的實例的返回值,就傳遞給的回調函數。基本介紹可見阮一峰老師的書籍。的狀態由決定,分成兩種情況。只有的狀態都變成,的狀態才會變成,此時的返回值組成一個數組,傳遞給的回調函數。 Promise源碼學習(2) 本篇為上一篇源碼學習(1)的補充,主要是來介紹Promise.all()和Promise.race()方法。閑話少敘...
閱讀 1610·2023-04-26 02:43
閱讀 3018·2021-11-11 16:54
閱讀 1351·2021-09-23 11:54
閱讀 1171·2021-09-23 11:22
閱讀 2367·2021-08-23 09:45
閱讀 852·2019-08-30 15:54
閱讀 3101·2019-08-30 15:53
閱讀 3189·2019-08-30 15:53