摘要:聲明,只是簡單地提了提的基本使用,大牛繞道先看一個例子你需要知道是個庫返回一個實例你可以把理解為,它們功能相近,只不過遵循規范我是第二個我是第二個為了防止你對這個鏈式調用看得眼花繚亂,我把這個給簡化一下成功回調失敗回調成功回調失敗回調,準備
聲明,只是簡單地提了提promise的基本使用,大牛繞道^_^1.先看一個例子
你需要知道
1.axios是個庫
2.axios()返回一個Promise實例
3.你可以把axios()理解為$.ajax(),它們功能相近,只不過axios遵循promise規范
axios({ url: "." }).then((resolve) => { console.log(resolve) return "我是第二個then" }, (reject) => { console.log(reject) }).then((resolve_2) => { console.log(resolve_2) // "我是第二個then" }, (reject_2) => { console.log(reject_2) })
為了防止你對這個鏈式調用看得眼花繚亂,我把這個給簡化一下
axios({ url: "." }).then(成功回調, 失敗回調) .then(成功回調2, 失敗回調2)
ok,準備好了嗎?下面我們先來了解Promise的一些基本概念
2.Promise的基本概念 2.1Promise的作用Promise是專門用來解決異步編程問題的,避免了層層嵌套的回調函數[Callback Hell]
下面是一個用傳統方法Callback Hell來寫的異步代碼
可以非常明顯地看出來,Callback Hell的方式讓代碼的可讀性變得非常差
function loadImg(src, callback, fail) { let img = new Image() img.onload = function () { // 成功回調 callback(img) } img.onerror = fail // 失敗回調 img.src = src } let src = "https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png" loadImg(src, function (img) { console.log(img.width) }, function () { console.log("error") })2.2 Promise的三個狀態
pending初始態,既不成功也不失敗
fulfilled異步操作成功
rejected異步操作失敗
Promise對象代表一個異步操作,且只有異步操作的結果,可以決定當前是哪一種狀態,任何其他操作都無法改變這個狀態,peding可轉化為fulfilled與rejected,但fulfilled與rejected不可相互轉化
那知道這三個狀態又有什么用咧?
OK,我們看下面的代碼
axios({ url: "." }).then(成功回調, 失敗回調)
axios({url: "."})
異步操作成功代表了pending -> fulfilled -> then里的第一個參數【成功回調】
異步操作失敗代表了pending -> rejected -> then里的第二個參數【失敗回調】
因為 Promise.prototype.then 和 Promise.prototype.catch 方法返回promise 對象
所以它們可以被鏈式調用。
OK,下面讓我們仔細看一下回調觸發機制究竟怎樣的過程
axios({ url: "." }).then(成功回調, 失敗回調) .then(成功回調2, 失敗回調2)
是不是看的有點暈?沒關系,下面我來詳細解釋一下
1.異步操作成功 -> 進入第一個then的成功回調 -> 成功回調執行異步操作成功 -> 由于又返回了一個Promise實例,其狀態由于異步操作成功,由pending轉為了fullfiled,所以還可以再調用第二個then -> 進入第二個then的成功回調2
2.異步操作失敗-> 進入第一個then的失敗回調 -> 失敗回調執行異步操作成功 -> 由于又返回了一個Promise實例,其狀態由于異步操作成功,由pending轉為了fullfiled,所以還可以再調用第二個then -> 進入第二個then的成功回調2
你的問題:
1.為什么第一個then不論調用成功回調還是失敗回調,第二個then都會調用成功回調2呢
答:因為第二個then調用進入哪個回調函數,完全是看第一個then返回的Promise是什么狀態,換言之 —— 看異步操作成功與否
舉一個栗子
axios({ url: "." }).then((resolve) => { return xxx // 注意xxx是個未聲明的變量 // 瀏覽器會報錯,說明異步操作失敗了 // 所以第一個then返回的Promise的狀態是 rejected }, (reject) => {}) .then((resolve_2) => { console.log(1) }, (reject_2) => { // 所以第二個then只會調用它的第二個參數 console.log(2) })
2.你咋不提catch咧?
因為catch就是then的一個語法糖呀
catch等價于then只有第二個參數【失敗回調】的形式
上面的例子用catch,可以這么寫
axios({ url: "." }).then((fulfilled) => { return xxx // 注意xxx是個未聲明的變量 // 所以第一個then返回的Promise的狀態是 rejected }, (rejected) => { }).catch((rejected) => { // 所以直接進入catch console.log(2) })4.自己寫一個Promise
第一步
// 聲明一個函數 讓這個函數返回一個Promise實例 let setPromise = function () { return new Promise() }
第二步
// new Promise()接受一個函數 // 規定這個函數必須要有兩個參數【成功回調,失敗回調】 let a = 0 let setPromise = function () { let fn = (x, y) => { setTimeout(() => { x("success") // 一定要寫上異步操作成功后,會調用的回調函數 }, 2000) } return new Promise(fn) // 在new的過程中一定有一句fn.call(undefined, fulfilled, rejected) }
第三步
// 寫的更裝逼點,順別把x,y換個名字【其實是規定】 let setPromise = function () { return new Promise((resolve, reject) => { setTimeout(() => { resolve("success") }, 2000) }) // 在new的過程中一定有一句fn.call(undefined, fulfilled, rejected) }
第四步
// 你要做什么,就用then輸入到這個Promise實例里面去 let promiseInstance = setPromise() promiseInstance.then((success) => { console.log(success) // "success" }, () => { console.log("失敗啦") })
總結
let setPromise = function () { return new Promise((resolve, reject) => { // 你的異步代碼 setTimeout(() => { resolve("success") // 給成功回調resolve傳遞一個參數 "success" console.log("測試一下") // 兩秒之后被執行 }, 2000) }) } // 你要做什么,就用then輸入到這個Promise實例里面去 let promiseInstance = setPromise() promiseInstance.then((resolve) => { // 異步操作執行成功后執行 console.log(resolve) // "success" console.log("完美運行") // "完美運行" }, () => { console.log("失敗啦") })5.最后
其實對于Promise和then有一個更具象化的理解
Promise的中文翻譯是承諾,then的中文翻譯是然后
所以,你可以想象你去買橘子,結果店里沒有進貨,店員對你Promise,只要他店里到貨,then他就會通知你
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/93767.html
摘要:主要邏輯本質上還是回調函數那一套。通過的判斷完成異步和同步的區分。 主要邏輯: 本質上還是回調函數那一套。通過_subscribers的判斷完成異步和同步的區分。通過 resolve,reject -> publish -> invokeCallback -> resolve,reject的遞歸和下一條then的parent是上一條的child來完成then鏈的流轉 同步情況...
摘要:常見應用則是為了完成一些更新應用程序狀態的較小的任務,如處理的回調和的修改,以便讓這些任務在瀏覽器重新渲染之前執行。常見應用執行順序的實現需要至少一個和至少一個。 簡介 我們在上一篇 《淺析 JS 中的EventLoop 事件循環》 中提到一個 Event Queue,其實在事件循環中 queue 一共有兩種,還有一種叫 Job Queue 其中 Event Queue 在 HTML...
摘要:核心的異步延遲函數,用于異步延遲調用函數優先使用原生原本支持更廣,但在的中,觸摸事件處理程序中觸發會產生嚴重錯誤的,回調被推入隊列但是隊列可能不會如期執行。 淺析 Vue 2.6 中的 nextTick 方法。 事件循環 JS 的 事件循環 和 任務隊列 其實是理解 nextTick 概念的關鍵。這個網上其實有很多優質的文章做了詳細介紹,我就簡單過過了。 以下內容適用于瀏覽器端 JS,...
摘要:淺析的特點之一就是響應式,但數據更新時,并不會立即更新。盡管已經更新,但新增的元素并不立即插入到中。實際在中,執行了,這也是自動綁定到執行上下文的原因。在內,使用數組保存回調函數,表示當前狀態,使用函數來執行回調隊列。 Vue.nextTick 淺析 Vue 的特點之一就是響應式,但數據更新時,DOM 并不會立即更新。當我們有一個業務場景,需要在 DOM 更新之后再執行一段代碼時,可以...
摘要:前言業務開發中經常會用到異步函數,這里簡單的對異步函數以及它的各種各樣的解決方案做一個淺析優缺點優點能夠極大的提高程序并發業務邏輯的能力缺點異步函數的書寫方式和代碼執行邏輯很不直觀,回調函數這種方式不太符合人類的的線性思維異步函數的執行流程 前言 業務開發中經常會用到異步函數,這里簡單的對異步函數以及它的各種各樣的解決方案做一個淺析 優缺點: 優點: 能夠極大的提高程序并發業務邏輯的能...
閱讀 830·2021-11-22 11:59
閱讀 3247·2021-11-17 09:33
閱讀 2316·2021-09-29 09:34
閱讀 1947·2021-09-22 15:25
閱讀 1963·2019-08-30 15:55
閱讀 1326·2019-08-30 15:55
閱讀 537·2019-08-30 15:53
閱讀 3352·2019-08-29 13:55