欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JS使用Promise時常見的5個錯誤總結(jié)

 更新時間:2022年11月10日 10:52:05   作者:前端小智  
Promise?提供了一種優(yōu)雅的方法來處理?JS?中的異步操作。這也是避免“回調(diào)地獄”的解決方案。然而,并沒有多少開發(fā)人員了解其中的內(nèi)容。因此,許多人在實踐中往往會犯錯誤。在本文中,介紹一下使用?promise?時的五個常見錯誤,希望大家能夠避免

Promise 提供了一種優(yōu)雅的方法來處理 JS 中的異步操作。這也是避免“回調(diào)地獄”的解決方案。然而,并沒有多少開發(fā)人員了解其中的內(nèi)容。因此,許多人在實踐中往往會犯錯誤。

在本文中,介紹一下使用 promise 時的五個常見錯誤,希望大家能夠避免這些錯誤。

1.避免 Promise 地獄

通常,Promise是用來避免回調(diào)地獄。但濫用它們也會導(dǎo)致 Promise是地獄。

userLogin('user').then(function(user){
    getArticle(user).then(function(articles){
        showArticle(articles).then(function(){
            //Your code goes here...
        });
    });
});

在上面的例子中,我們對 userLogin、getararticle 和 showararticle 嵌套了三個promise。這樣復(fù)雜性將按代碼行比例增長,它可能變得不可讀。

為了避免這種情況,我們需要解除代碼的嵌套,從第一個 then 中返回 getArticle,然后在第二個 then 中處理它。

userLogin('user')
  .then(getArticle)
  .then(showArticle)
  .then(function(){
       //Your code goes here...
});

2.在 Promise 中使用 try/catch 塊

通常情況下,我們使用 try/catch 塊來處理錯誤。然而,不建議在 Promise 對象中使用try/catch 。

這是因為如果有任何錯誤,Promise對象會在 catch 內(nèi)自動處理。

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 內(nèi)使用了 try/catch 塊。

但是,Promise本身會在其作用域內(nèi)捕捉所有的錯誤(甚至是打字錯誤),而不需要 try/catch塊。它確保在執(zhí)行過程中拋出的所有異常都被獲取并轉(zhuǎn)換為被拒絕的 Promise。

new Promise((resolve, reject) => {
  const data = doThis();
  // do something
  resolve()
})
  .then(data => console.log(data))
  .catch(error => console.log(error));

注意:在 Promise 塊中使用 .catch() 塊是至關(guān)重要的。否則,你的測試案例可能會失敗,而且應(yīng)用程序在生產(chǎn)階段可能會崩潰。

3.在 Promise 塊內(nèi)使用異步函數(shù)

Async/Await 是一種更高級的語法,用于處理同步代碼中的多個Promise。當我們在一個函數(shù)聲明前使用 async 關(guān)鍵字時,它會返回一個 Promise,我們可以使用 await 關(guān)鍵字來停止代碼,直到我們正在等待的Promise解決或拒絕。

但是,當你把一個 Async 函數(shù)放在一個 Promise 塊里面時,會有一些副作用。

假設(shè)我們想在Promise 塊中做一個異步操作,所以使用了 async 關(guān)鍵字,但,不巧的是我們的代碼拋出了一個錯誤。

這樣,即使使用 catch() 塊或在 try/catch 塊內(nèi)等待你的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塊內(nèi)遇到 async 函數(shù)時,我試圖將 async 邏輯保持在 Promise 塊之外,以保持其同步性。10次中有9次都能成功。

然而,在某些情況下,可能需要一個 async 函數(shù)。在這種情況下,也別無選擇,只能用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.在創(chuàng)建 Promise 后立即執(zhí)行 Promise 塊

至于下面的代碼片斷,如果我們把代碼片斷放在調(diào)用HTTP請求的地方,它就會被立即執(zhí)行。

const myPromise = new Promise(resolve => {
  // code to make HTTP request
  resolve(result);
});

原因是這段代碼被包裹在一個Promise構(gòu)造函數(shù)中。然而,有些人可能會認為只有在執(zhí)行myPromise 的then方法之后才被觸發(fā)。

然而,真相并非如此。相反,當一個Promise被創(chuàng)建時,回調(diào)被立即執(zhí)行。

這意味著在建立 myPromise 之后到達下面一行時,HTTP請求很可能已經(jīng)在運行,或者至少處于調(diào)度狀態(tài)。

Promises 總是急于執(zhí)行過程。

但是,如果希望以后再執(zhí)行 Promises,應(yīng)該怎么做?如果現(xiàn)在不想發(fā)出HTTP請求怎么辦?是否有什么神奇的機制內(nèi)置于 Promises 中,使我們能夠做到這一點?

答案就是使用函數(shù)。函數(shù)是一種耗時的機制。只有當開發(fā)者明確地用 () 來調(diào)用它們時,它們才會執(zhí)行。簡單地定義一個函數(shù)還不能讓我們得到什么。所以,讓 Promise 變得懶惰的最有效方法是將其包裹在一個函數(shù)中!

const createMyPromise = () => new Promise(resolve => {
  // HTTP request
  resolve(result);
});

對于HTTP請求,Promise 構(gòu)造函數(shù)和回調(diào)函數(shù)只有在函數(shù)被執(zhí)行時才會被調(diào)用。所以現(xiàn)在我們有一個懶惰的Promise,只有在我們需要的時候才會執(zhí)行。

5.不一定使用 Promise.all() 方法

如果你已經(jīng)工作多年,應(yīng)該已經(jīng)知道我在說什么了。如果有許多彼此不相關(guān)的 Promise,我們可以同時處理它們。

Promise 是并發(fā)的,但如你一個一個地等待它們,會太費時間,Promise.all()可以節(jié)省很多時間。

記住,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');  
})();

上述代碼的執(zhí)行時間約為 6 秒。但如果我們用 Promise.all() 代替它,將減少執(zhí)行時間。

(async () => {
    console.time('concurrent');
    await Promise.all([f1(), f2(), f3()]);
    console.timeEnd('concurrent'); 
  })();

總結(jié)

在這篇文章中,我們討論了使用 Promise 時常犯的五個錯誤。然而,可能還有很多簡單的問題需要仔細解決。

到此這篇關(guān)于JS使用Promise時常見的5個錯誤總結(jié)的文章就介紹到這了,更多相關(guān)JS Promise錯誤內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • js中如何往對象中添加屬性

    js中如何往對象中添加屬性

    這篇文章主要介紹了js中如何往對象中添加屬性,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • JavaScript中執(zhí)行上下文和執(zhí)行棧

    JavaScript中執(zhí)行上下文和執(zhí)行棧

    這篇文章主要介紹了JavaScript中執(zhí)行上下文和執(zhí)行棧,執(zhí)行上下文是評估和執(zhí)行JavaScript代碼的環(huán)境的抽象概念,更多相關(guān)介紹,感興趣的朋友可以參考一下
    2022-09-09
  • JavaScript實現(xiàn)漢字轉(zhuǎn)換為拼音的庫文件示例

    JavaScript實現(xiàn)漢字轉(zhuǎn)換為拼音的庫文件示例

    這篇文章主要介紹了JavaScript實現(xiàn)漢字轉(zhuǎn)換為拼音的庫文件,結(jié)合具體實例分析了JSPinyin庫文件與簡單使用技巧,需要的朋友可以參考下
    2016-12-12
  • JavaScript構(gòu)建自己的對象示例

    JavaScript構(gòu)建自己的對象示例

    這篇文章主要介紹了JavaScript構(gòu)建自己的對象,結(jié)合實例形式分析了javascript自定義類的定義與對象的實例化相關(guān)操作技巧,需要的朋友可以參考下
    2016-11-11
  • 微信小程序?qū)崿F(xiàn)登錄界面

    微信小程序?qū)崿F(xiàn)登錄界面

    這篇文章主要為大家詳細介紹了微信小程序?qū)崿F(xiàn)登錄界面,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-04-04
  • JavaScript async/await原理及實例解析

    JavaScript async/await原理及實例解析

    這篇文章主要介紹了JavaScript async/await原理及實例解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-12-12
  • 10個很少使用的JavaScript?Console方法分享

    10個很少使用的JavaScript?Console方法分享

    你一定聽說過?console.log()?,而且可能一直在使用它,在本文中,我們將探討一些最有用的控制臺方法,以及它們在數(shù)據(jù)可視化、調(diào)試等方面的用途,感興趣的小伙伴可以學(xué)習(xí)一下
    2023-09-09
  • JS通過ajax動態(tài)讀取xml文件內(nèi)容的方法

    JS通過ajax動態(tài)讀取xml文件內(nèi)容的方法

    這篇文章主要介紹了JS通過ajax動態(tài)讀取xml文件內(nèi)容的方法,實例分析了Ajax操作XML文件的技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-03-03
  • 詳解JSONObject和JSONArray區(qū)別及基本用法

    詳解JSONObject和JSONArray區(qū)別及基本用法

    這篇文章主要介紹了詳解JSONObject和JSONArray區(qū)別及基本用法,需要的朋友可以參考下
    2017-10-10
  • Javascript將圖片的絕對路徑轉(zhuǎn)換為base64編碼的方法

    Javascript將圖片的絕對路徑轉(zhuǎn)換為base64編碼的方法

    這篇文章主要介紹了Javascript將圖片的絕對路徑轉(zhuǎn)換為base64編碼的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-01-01

最新評論