首頁 web前端 js教程 快速避坑,聊聊5個用promise的常見錯誤!

快速避坑,聊聊5個用promise的常見錯誤!

Dec 08, 2021 am 10:22 AM
javascript promise 常見錯誤

這篇文章跟大家分享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...
        });
    });
});
登入後複製

在上面的範例中,我們對 userLogingetararticleshowararticle 嵌套了三個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(&#39;message&#39;);
}).catch(e => console.log(e.message));

(async () => {
  try {
    await new Promise(async () => {
      throw new Error(&#39;message&#39;);
    });
  } catch (e) {
    console.log(e.message);
  }
})();
登入後複製

當我在Promise區塊內遇到 async 函數時,我試圖將 async 邏輯保持在 Promise 區塊之外,以保持其同步性。 10次​​中有9次都能成功。

然而,在某些情況下,可能需要一個 async 函數。在這種情況下,也別無選擇,只能用try/catch 區塊來手動管理。

new Promise(async (resolve, reject) => {
  try {
    throw new Error(&#39;message&#39;);
  } 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(&#39;message&#39;);
      } 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建構函式中。然而,有些人可能會認為只有在執行myPromisethen方法之後才被觸發。

然而,真相並非如此。相反,當一個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(&#39;util&#39;);
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(&#39;sequential&#39;);
  await f1();
  await f2();
  await f3();
  console.timeEnd(&#39;sequential&#39;);  
})();
登入後複製

上述代码的执行时间约为 6 秒。但如果我们用 Promise.all() 代替它,将减少执行时间。

(async () => {
    console.time(&#39;concurrent&#39;);
    await Promise.all([f1(), f2(), f3()]);
    console.timeEnd(&#39;concurrent&#39;); 
  })();
登入後複製

总结

在这篇文章中,我们讨论了使用 Promise 时常犯的五个错误。然而,可能还有很多简单的问题需要仔细解决。

如果你还有更多相关的错误,欢迎留言一起讨论。

英文原文地址:https://blog.bitsrc.io/5-common-mistakes-in-using-promises-bfcc4d62657f

作者:Ravidu Perera

更多编程相关知识,请访问:编程入门!!

以上是快速避坑,聊聊5個用promise的常見錯誤!的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
威爾R.E.P.O.有交叉遊戲嗎?
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

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

如何使用WebSocket和JavaScript實現線上語音辨識系統 如何使用WebSocket和JavaScript實現線上語音辨識系統 Dec 17, 2023 pm 02:54 PM

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

WebSocket與JavaScript:實現即時監控系統的關鍵技術 WebSocket與JavaScript:實現即時監控系統的關鍵技術 Dec 17, 2023 pm 05:30 PM

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

如何利用JavaScript和WebSocket實現即時線上點餐系統 如何利用JavaScript和WebSocket實現即時線上點餐系統 Dec 17, 2023 pm 12:09 PM

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

如何使用WebSocket和JavaScript實現線上預約系統 如何使用WebSocket和JavaScript實現線上預約系統 Dec 17, 2023 am 09:39 AM

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

言出必行:兌現承諾的好處和壞處 言出必行:兌現承諾的好處和壞處 Feb 18, 2024 pm 08:06 PM

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

JavaScript與WebSocket:打造高效率的即時天氣預報系統 JavaScript與WebSocket:打造高效率的即時天氣預報系統 Dec 17, 2023 pm 05:13 PM

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

簡易JavaScript教學:取得HTTP狀態碼的方法 簡易JavaScript教學:取得HTTP狀態碼的方法 Jan 05, 2024 pm 06:08 PM

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

深入了解Promise.resolve() 深入了解Promise.resolve() Feb 18, 2024 pm 07:13 PM

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

See all articles