快速避坑,聊聊5個用promise的常見錯誤!
這篇文章跟大家分享5個使用 promise 時的常見錯誤,幫大家快速避坑,希望對大家有幫助!
Promise 提供了一種優雅的方法來處理 JS 中的非同步操作。這也是避免「回調地獄」的解決方案。然而,並沒有太多開發人員了解其中的內容。因此,許多人在實踐中往往會犯錯。 【相關推薦:javascript學習教學】
在本文中,介紹一下使用 promise 時的五個常見錯誤,希望大家能夠避免這些錯誤。
1.避免 Promise 地獄
#通常,Promise是用來避免回調地獄。但濫用它們也會導致 Promise是地獄。
userLogin('user').then(function(user){ getArticle(user).then(function(articles){ showArticle(articles).then(function(){ //Your code goes here... }); }); });
在上面的範例中,我們對 userLogin
、getararticle
和 showararticle
嵌套了三個promise。這樣複雜性將按程式碼行比例增長,它可能變得不可讀。
為了避免這種情況,我們需要解除程式碼的巢狀,從第一個then
中傳回getArticle
,然後在第二個then
中處理它。
userLogin('user') .then(getArticle) .then(showArticle) .then(function(){ //Your code goes here... });
2. 在Promise 中使用<span style="font-size: 18px;">#try/catch</span>
區塊
通常情況下,我們使用try/catch
區塊來處理錯誤。然而,不建議在 Promise
物件中使用try/catch
。
這是因為如果有任何錯誤,Promise物件會在 catch
內自動處理。
ew Promise((resolve, reject) => { try { const data = doThis(); // do something resolve(); } catch (e) { reject(e); } }) .then(data => console.log(data)) .catch(error => console.log(error));
在上面的範例中,我們在Promise 內使用了 try/catch
區塊。
但是,Promise本身會在其作用域內捕捉所有的錯誤(甚至是打字錯誤),而不需要 try/catch
區塊。它確保在執行過程中拋出的所有異常都被獲取並轉換為被拒絕的 Promise。
new Promise((resolve, reject) => { const data = doThis(); // do something resolve() }) .then(data => console.log(data)) .catch(error => console.log(error));
注意:在 Promise 區塊中使用 .catch()
區塊是至關重要的。否則,你的測試案例可能會失敗,而且應用程式在生產階段可能會崩潰。
3. 在Promise 區塊內使用非同步函數
Async/Await
是更高階的語法,用於處理同步程式碼中的多個Promise。當我們在一個函數宣告前使用async
關鍵字時,它會傳回一個Promise,我們可以使用await
關鍵字來停止程式碼,直到我們正在等待的Promise解決或拒絕。
但是,當你把一個 Async 函數放在一個 Promise 區塊裡面時,會有一些副作用。
假設我們想要在Promise 區塊中做一個非同步操作,所以使用了 async
關鍵字,但,不巧的是我們的程式碼拋出了一個錯誤。
這樣,即使使用 catch()
區塊或在 try/catch
區塊內等待你的Promise,我們也不能立即處理這個錯誤。請看下面的例子。
// 此代码无法处理错误 new Promise(async () => { throw new Error('message'); }).catch(e => console.log(e.message)); (async () => { try { await new Promise(async () => { throw new Error('message'); }); } catch (e) { console.log(e.message); } })();
當我在Promise區塊內遇到 async
函數時,我試圖將 async
邏輯保持在 Promise 區塊之外,以保持其同步性。 10次中有9次都能成功。
然而,在某些情況下,可能需要一個 async
函數。在這種情況下,也別無選擇,只能用try/catch
區塊來手動管理。
new Promise(async (resolve, reject) => { try { throw new Error('message'); } catch (error) { reject(error); } }).catch(e => console.log(e.message)); //using async/await (async () => { try { await new Promise(async (resolve, reject) => { try { throw new Error('message'); } catch (error) { reject(error); } }); } catch (e) { console.log(e.message); } })();
4.在建立Promise 後立即執行Promise 區塊
至於下面的程式碼片段,如果我們把程式碼片段放在呼叫HTTP請求的地方,它就會被立即執行。
const myPromise = new Promise(resolve => { // code to make HTTP request resolve(result); });
原因是這段程式碼被包裹在一個Promise建構函式中。然而,有些人可能會認為只有在執行myPromise
的then
方法之後才被觸發。
然而,真相並非如此。相反,當一個Promise被創建時,回調會立即執行。
這表示在建立 myPromise
之後到達下面一行時,HTTP請求很可能已經在運行,或至少處於調度狀態。
Promises 總是急於執行程序。
但是,如果希望以後再執行 Promises,該怎麼做?如果現在不想發出HTTP請求怎麼辦?是否有什麼神奇的機制內建在 Promises 中,使我們能夠做到這一點?
答案就是使用函數。函數是一種耗時的機制。只有當開發者明確地用 ()
來呼叫它們時,它們才會執行。簡單地定義一個函數還不能讓我們得到什麼。所以,讓 Promise 變得懶惰的最有效方法是將其包裹在一個函數中!
const createMyPromise = () => new Promise(resolve => { // HTTP request resolve(result); });
对于HTTP请求,Promise 构造函数和回调函数只有在函数被执行时才会被调用。所以现在我们有一个懒惰的Promise,只有在我们需要的时候才会执行。
5. 不一定使用 Promise.all() 方法
如果你已经工作多年,应该已经知道我在说什么了。如果有许多彼此不相关的 Promise,我们可以同时处理它们。
Promise 是并发的,但如你一个一个地等待它们,会太费时间,Promise.all()
可以节省很多时间。
记住,Promise.all() 是我们的朋友
const { promisify } = require('util'); const sleep = promisify(setTimeout); async function f1() { await sleep(1000); } async function f2() { await sleep(2000); } async function f3() { await sleep(3000); } (async () => { console.time('sequential'); await f1(); await f2(); await f3(); console.timeEnd('sequential'); })();
上述代码的执行时间约为 6
秒。但如果我们用 Promise.all()
代替它,将减少执行时间。
(async () => { console.time('concurrent'); await Promise.all([f1(), f2(), f3()]); console.timeEnd('concurrent'); })();
总结
在这篇文章中,我们讨论了使用 Promise 时常犯的五个错误。然而,可能还有很多简单的问题需要仔细解决。
如果你还有更多相关的错误,欢迎留言一起讨论。
英文原文地址:https://blog.bitsrc.io/5-common-mistakes-in-using-promises-bfcc4d62657f
作者:Ravidu Perera
更多编程相关知识,请访问:编程入门!!
以上是快速避坑,聊聊5個用promise的常見錯誤!的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

熱門話題

如何使用WebSocket和JavaScript實現線上語音辨識系統引言:隨著科技的不斷發展,語音辨識技術已成為了人工智慧領域的重要組成部分。而基於WebSocket和JavaScript實現的線上語音辨識系統,具備了低延遲、即時性和跨平台的特點,成為了廣泛應用的解決方案。本文將介紹如何使用WebSocket和JavaScript來實現線上語音辨識系

WebSocket與JavaScript:實現即時監控系統的關鍵技術引言:隨著互聯網技術的快速發展,即時監控系統在各個領域中得到了廣泛的應用。而實現即時監控的關鍵技術之一就是WebSocket與JavaScript的結合使用。本文將介紹WebSocket與JavaScript在即時監控系統中的應用,並給出程式碼範例,詳細解釋其實作原理。一、WebSocket技

如何利用JavaScript和WebSocket實現即時線上點餐系統介紹:隨著網路的普及和技術的進步,越來越多的餐廳開始提供線上點餐服務。為了實現即時線上點餐系統,我們可以利用JavaScript和WebSocket技術。 WebSocket是一種基於TCP協定的全雙工通訊協議,可實現客戶端與伺服器的即時雙向通訊。在即時線上點餐系統中,當使用者選擇菜餚並下訂單

如何使用WebSocket和JavaScript實現線上預約系統在當今數位化的時代,越來越多的業務和服務都需要提供線上預約功能。而實現一個高效、即時的線上預約系統是至關重要的。本文將介紹如何使用WebSocket和JavaScript來實作一個線上預約系統,並提供具體的程式碼範例。一、什麼是WebSocketWebSocket是一種在單一TCP連線上進行全雙工

在日常生活中,我們常常會遇到承諾與兌現之間的問題。無論是在個人關係中,或是在商業交易中,承諾的兌現都是建立信任的關鍵。然而,承諾的利與弊也常常會引起爭議。本文將探討承諾的利與弊,並給予一些建議,如何做到言出必行。承諾的利是顯而易見的。首先,承諾可以建立信任。當一個人信守承諾時,他會讓別人相信自己是個可信賴的人。信任是人與人之間建立的紐帶,它可以讓人們更加

JavaScript和WebSocket:打造高效的即時天氣預報系統引言:如今,天氣預報的準確性對於日常生活以及決策制定具有重要意義。隨著技術的發展,我們可以透過即時獲取天氣數據來提供更準確可靠的天氣預報。在本文中,我們將學習如何使用JavaScript和WebSocket技術,來建立一個高效的即時天氣預報系統。本文將透過具體的程式碼範例來展示實現的過程。 We

JavaScript教學:如何取得HTTP狀態碼,需要具體程式碼範例前言:在Web開發中,經常會涉及到與伺服器進行資料互動的場景。在與伺服器進行通訊時,我們經常需要取得傳回的HTTP狀態碼來判斷操作是否成功,並根據不同的狀態碼來進行對應的處理。本篇文章將教你如何使用JavaScript來取得HTTP狀態碼,並提供一些實用的程式碼範例。使用XMLHttpRequest

Promise.resolve()詳解,需要具體程式碼範例Promise是JavaScript中一種用來處理非同步操作的機制。在實際開發中,常常需要處理一些需要依序執行的非同步任務,而Promise.resolve()方法就是用來傳回一個已經Fulfilled狀態的Promise物件。 Promise.resolve()是Promise類別的靜態方法,它接受一個
