摘要:的種狀態對象一共有進行中,已成功和已失敗種狀態。如果執行成功,將返回一個數組,數組的值和實例的返回值一一對應。如果返回失敗,會被自己的方法捕獲,經過處理后返回一個成功的實例,返回值是失敗狀態返回的,最后也就返回成功狀態。
寫東西真是難啊,一是因為肚子里沒多少貨,二是因為掌握的東西也太細碎表面。好吧,這也是為什么要寫的原因,希望能借此倒逼一下自己。
本來想著一個主題接一個主題的來寫,但是發現好難。好吧,那就從自己熟悉的東西開始寫。
Promise長啥樣先看大致的代碼
new Promise(function (resolve, reject) { // 執行異步操作...... // 判斷異步操作的結果 if (/* success */) { resolve(value); } else { reject(err); } }).then(res => { // 成功,執行后續操作 }).catch(err => { // 失敗,處理錯誤 })
Promise的字面意思就是承諾,承諾表示表示將要做但是還未做的事情,而且承諾還伴隨著這件事情是成功或者失敗的反饋。所以當new一個Promise的時候,就相當于告訴js引擎去幫我們執行一些操作(同步或者異步的都可以),執行完后再告訴我們結果,然后我們再根據結果的成功與否去做之后的操作。
舉個栗子console.log("start...") new Promise(function (resolve, reject) { console.log("start promise...") // 大約0.5秒后執行 setTimeout(() => { console.log("start timeout...") // 隨機生成一個num,1 <= num <= 10 const num = parseInt(Math.random() * 10) + 1 // 大于5算成功,否則算失敗 if (num > 5) { resolve("success") } else { reject("failed") } console.log("end timeout...") }, 500) console.log("end promise...") }).then(res => { console.log(res) }).catch(err => { console.log(err) }) console.log("end...")
運行結果:
start...
start promise...
end promise...
end...
start timeout...
end timeout...
failed/success
這段代碼,首先會打印出start...字符串,然后當我們new Promise()的時候,引擎會立刻執行Promise里的代碼,所以打印出start promise...。緊接著,遇到setTimeout,所以直接跳到end priomise...處打印該字符串。這個時候,Promise里的代碼暫時執行完畢,引擎將切換到Promise外部執行后續的同步代碼,打印出end...。大約在0.5秒后,引擎將切回Primise內部執行setTimeout的回調函數,于是打印出start timeout...,但是不管resolve還是reject,只要沒有return語句,都將打印出end promise...,最后才是執行then或者catch里的回調函數。
Promise的3種狀態Promise對象一共有pedding(進行中),fulfilled(已成功)和rejected(已失敗)3種狀態。從創建Promise到resolve函數執行之前,都是pedding狀態,resolve()執行后變成fulfilled狀態,reject()執行后變成rejected狀態。
Promise的then方法Promise的then方法是在Promise的狀態改變時調用,接收兩個參數,第一個參數是成功時的回調函數,第二個參數(可選)是失敗時的回調函數。
then方法會返回一個新的Promise實例,于是我們可以繼續在then后面寫then(catch方法同樣返回Promise實例,可以鏈式調用)。這個特性挺有用的,下面用示例說一下。
首先,先創建一個函數,該函數返回一個Promise實例,該Promise成功或失敗的概率各50%。
const isMoreThanFive = function () { return new Promise(function (resolve, reject) { setTimeout(() => { const num = parseInt(Math.random() * 10) + 1 if (num > 5) { resolve("success") } else { reject("failed") } }, 500) }) }
一個then函數的情況:
isMoreThanFive() .then((res) => { console.log(res) }) .catch(err => { console.log(err) }) // 0.5秒后輸出success或者failed
兩個then函數的情況:
isMoreThanFive() .then((res) => { console.log("first " + res); return isMoreThanFive() }) .then(res => { console.log("second " + res); }) .catch(err => { console.log(err) })
這種情況,如果第一個isMoreThanFive執行失敗,將直接執行catch回調,如果成功,會執行第一個then方法,then方法里又通過isMoreThanFive返回了一個新的Promise實例,這時,如果新的Promise成功將執行第二個then方法,如果失敗將執行catch方法。
末尾的catch方法會捕獲到前面Promise出現的所有異常,包括reject返回的失敗狀態和代碼執行過程中發生的錯誤,所以一般會省略then方法的第二個參數(處理失敗時的回調),而直接在最后添加catch方法統一處理前面發生的錯誤。
在調用接口時,如果B接口依賴A接口返回的參數,這時,then的鏈式調用將非常方便。
先看代碼
const p1 = isMoreThanFive() const p2 = isMoreThanFive() Promise.all([p1, p2]) .then(res => { console.log(res) }) .catch(err => { console.log(err) }) // 輸出 failed 或者 ["success", "success"]
all方法接受一個數組,數組各項都是Promise實例。Promise.all會返回一個新的Promise實例,只有當數組內所有的Promise實例都成功時,all才返回成功狀態,否則只要有一個失敗都返回失敗狀態。如果all執行成功,將返回一個數組,數組的值和Promise實例的返回值一一對應。
注意,傳給all方法的所有Promise實例都是同時執行的,也就是說同時執行多個異步操作,如果某個實例失敗,則all方法直接返回失敗狀態,返回值由失敗的Promise實例提供。
這在前端渲染頁面時非常有用,利用Promise.all方法將可以同時請求多個接口,提升頁面的渲染速度。
特殊情況,當Promise實例有自己的catch方法時:
const p1 = isMoreThanFive() const p2 = isMoreThanFive() .catch(err => { return err }) Promise.all([p1, p2]) .then(res => { console.log(res) }) .catch(err => { console.log(err) }) // 輸出 failed 或者 ["success", "success"] 或者 [ "success", "failed" ]
如果傳入的Promise實例有自己的catch方法,就不會觸發Promise.all的catch方法。p2如果返回失敗,會被自己的catch方法捕獲,經過catch處理后返回一個resolved成功的Promise實例,返回值是失敗狀態返回的err,最后Promise.all也就返回成功狀態。
最后多帶帶使用Promise已經很方便很直觀了,但是如果配合上async函數的話,寫異步代碼完全可以使用同步的寫法,下一篇將會寫關于async的東西。
關于Promise,大致就是這些,沒有面面俱到,主要是把自己覺得經常用到的和重要的寫了下來。如果想了解更多的細節和原理可以看阮一峰老師的ES6教程。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/98262.html
摘要:的執行與狀態無關當得到狀態不論成功或失敗后就會執行,原文鏈接參考鏈接對象 同期異步系列文章推薦談一談javascript異步javascript異步中的回調javascript異步與promisejavascript異步之Promise.resolve()、Promise.reject()javascript異步之Promise then和catchjavascript異步之async...
摘要:到這里,我已經發出了一個請求買漢堡,啟動了一次交易。但是做漢堡需要時間,我不能馬上得到這個漢堡,收銀員給我一個收據來代替漢堡。到這里,收據就是一個承諾保證我最后能得到漢堡。 同期異步系列文章推薦談一談javascript異步javascript異步中的回調javascript異步之Promise.all()、Promise.race()、Promise.finally()javascr...
摘要:所以增加了異步函數,提高了代碼可讀性,對不太熟悉的人而言,幫助就更大了。因為異步函數去掉了所有回調。這就是此代碼有效的原因它和以下一樣代碼更易讀正如上面示例所見,與回調和代碼相比,異步函數代碼看起來非常簡單。 這篇文章詳細講解了JavaScript中的異步函數。 JavaScript中的異步代碼在很短的時間內從回調發展為Promise,再到ES2017的異步函數,現在我們可以像編寫同步...
摘要:從最開始的到封裝后的都在試圖解決異步編程過程中的問題。為了讓編程更美好,我們就需要引入來降低異步編程的復雜性。異步編程入門的全稱是前端經典面試題從輸入到頁面加載發生了什么這是一篇開發的科普類文章,涉及到優化等多個方面。 TypeScript 入門教程 從 JavaScript 程序員的角度總結思考,循序漸進的理解 TypeScript。 網絡基礎知識之 HTTP 協議 詳細介紹 HTT...
摘要:轉載自是什么呢根據的定義是一個被用于延時計算的最終結果的占位符這個怎么理解呢比如說,我要去麥當勞買點吃的,下單以后人家會先給你一個訂單號,等人家外賣做好了,會提示你,并用那個訂單小票來換取你真正的食物,在這時候,那個訂單小票就是你這頓飯的 轉載自: http://www.lht.ren/article/3/ Promise是什么呢?根據ecma-262的定義: Promise是一個被用...
閱讀 2251·2021-11-23 09:51
閱讀 1080·2021-11-22 15:35
閱讀 4867·2021-11-22 09:34
閱讀 1610·2021-10-08 10:13
閱讀 3026·2021-07-22 17:35
閱讀 2547·2019-08-30 15:56
閱讀 3088·2019-08-29 18:44
閱讀 3100·2019-08-29 15:32