摘要:前言使用中,鏈式的調用對于控制異步執行很重要。的鏈式調用是支持鏈式調用的,但是它是不同于上面的鏈式。是調用方法返回自身,但是是調用方法后返回一個新的。的運行機制請參考的運行機制值穿透由于通過沒有成功添加回調函數,發生了值穿透。
前言
使用Promise中,鏈式的調用對于控制異步執行很重要。
鏈式調用在jQuery的使用中,我們常常使用下面的代碼
$("#app").show().css("color","red");
這是因為jQuery的對象在調用上述方法的時候,會return此對象本身, 以方便后面可以繼續調用此對象的方法。
jQuery.fn.css = function(prop, value) { ...... return this; } jQuery.fn.show = function() { ...... return this; }Promise的鏈式調用
Promise是支持鏈式調用的,但是它是不同于上面jQuery的鏈式。jQeury是調用方法返回自身,但是Promise是調用方法后返回一個新的Promise。
const promise = new Promise((resolve, reject) => { resolve("ok"); }) const promise$1 = promise.then(() => {console.log()}); promise$1 === promise // false
可以看到上面的promise$1是不等于promise的,如果可以在node.js 或者在瀏覽器中進行斷點調試的話,還能看到promise$1的初始化狀態是pending的。
當Promise的實例使用then, catch, finally添加完回調方法以后,會返回一個初始化狀態為pending的Promise的實例對象。此對象的狀態我們在外部的程序是無法進行改變的,它的狀態取決于前面所注冊的回調方法的執行情況。 當回調方法運行正常,沒有產生錯誤或者異常,返回的值除Promise實例與本身(返回本身將會報錯),返回的Promise的實例對象狀態會變成resolved, 如果有錯誤或者異常,則會把狀態變為rejected。當然了返回值是Promise的實例對象,那么次Promise實例對象的狀態取決于返回的Promise實例對象的狀態。
下圖以then為例展示promise鏈式調用運行的流程
示例分析const promise$0 = Promise.resolve("resolve_0"); const promise$1 = new Promise((resolve, reject) => {resolve("resolve_1")}) promise$0.then((val) => { console.log(val) }).then(() => { console.log("continue") }); promise$1.then((val) => { console.log(val) }); //輸出結果: resolve_0 resolve_1 continue
promise$0與promise$1在使用then添加回掉函數之前,狀態已經從pending變為resolved,它們添加的回掉函數會被立即添加到Promise的運行隊列,promise$0.then((val) => { console.log(val) })返回的Promise實例需要等待所注冊的回調函數成功執行完畢以后,此Promise的狀態才從pending變為resolved。 Promise的運行機制請參考: Promise的運行機制
const promise = Promise.resolve("ok"); promise.then().then((val) => {console.log(val)}); // ok
由于promise通過then沒有成功添加回調函數,發生了值穿透。
const promise = Promise.resolve("complete"); promise.then((val) => { return new Promise ((resolve) => { resolve(val) console.log(val, 1); }) }) .then((val) => {console.log(val, 2)}) // complete 1 complete 2
我們把Promise暫命名(Pa), 通過promise.then返回的Promise(暫命名Pb), Pb狀態需要根據Pathen所注冊回調方法的運行,其回調方法返回一個新的Promise(暫命名Pc),由于返回的是Promise。Pb的狀態變成取決于Pc的狀態, 當Pc的狀態變化為resolved以后,Pb的狀態也變化為resolved。
var promise = Promise.resolve("ok"); promise.then(() => { throw new Error("error"); }).then(() => { console.log("continue"); }).then(() => { console.log("again"); }).catch(() => { }).then(() => { console.log("completed") }) // completed
在then所注冊的回調方法,發生異常以后,后續的Promise調用鏈的狀態都是rejected,導致后續的then(resolve)不會被推入Promise的運行隊列,也就不會被運行,直到這個錯誤被then(,reject) 或者catch捕獲。 而使用(then(,reject)) 或者catch注冊回調方法又會返回一個新的Promise,此Promise的狀態又只與它們所注冊的回調方法的執行相關。不會受到前面的影響。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/94313.html
摘要:從最開始的到封裝后的都在試圖解決異步編程過程中的問題。為了讓編程更美好,我們就需要引入來降低異步編程的復雜性。異步編程入門的全稱是前端經典面試題從輸入到頁面加載發生了什么這是一篇開發的科普類文章,涉及到優化等多個方面。 TypeScript 入門教程 從 JavaScript 程序員的角度總結思考,循序漸進的理解 TypeScript。 網絡基礎知識之 HTTP 協議 詳細介紹 HTT...
摘要:參數如前面所提到的,方法只是方法的一個語法糖,原因就在于方法的參數為實際上是兩個回調函數,分別用于處理調用它的對象的和狀態,而方法就等價于狀態處理函數。對象狀態傳遞和改變的方法利用回調的返回值,可以控制某個操作后方法返回的對象及其狀態。 注意,本文主要針對ES6標準實現的Promise語法進行闡述,實例代碼也都使用ES6語法,快速入門ES6請參見ECMAScript 6 掃盲。 一分鐘...
摘要:事件循環從回調隊列中獲取并將其推入調用堆棧。執行從調用堆棧中移除從調用堆棧中移除快速回顧值得注意的是,指定了事件循環應該如何工作,這意味著在技術上它屬于引擎的職責范圍,不再僅僅扮演宿主環境的角色。 此篇是 JavaScript是如何工作的第四篇,其它三篇可以看這里: JavaScript是如何工作的:引擎,運行時和調用堆棧的概述! JavaScript是如何工作的:深入V8引擎&編寫...
摘要:忍者級別的函數操作對于什么是匿名函數,這里就不做過多介紹了。我們需要知道的是,對于而言,匿名函數是一個很重要且具有邏輯性的特性。通常,匿名函數的使用情況是創建一個供以后使用的函數。 JS 中的遞歸 遞歸, 遞歸基礎, 斐波那契數列, 使用遞歸方式深拷貝, 自定義事件添加 這一次,徹底弄懂 JavaScript 執行機制 本文的目的就是要保證你徹底弄懂javascript的執行機制,如果...
摘要:回調函數模式類似于事件模型,因為異步代碼也會在后面的一個時間點才執行如果回調過多,會陷入回調地獄基礎可以當做是一個占位符,表示異步操作的執行結果。函數可以返回一個,而不必訂閱一個事件或者向函數傳遞一個回調函數。 主要知識點:Promise生命周期、Promise基本操作、Promise鏈、響應多個Promise以及集成PromiseshowImg(https://segmentfaul...
閱讀 2022·2023-04-25 23:30
閱讀 1452·2021-11-24 10:18
閱讀 3069·2021-10-09 09:54
閱讀 2017·2021-10-08 10:05
閱讀 3431·2021-09-23 11:21
閱讀 3161·2019-08-30 15:52
閱讀 1560·2019-08-30 13:05
閱讀 1056·2019-08-30 13:02