<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          【JS】1170- 5 個使用 Promise 時的常見錯誤

          共 4175字,需瀏覽 9分鐘

           ·

          2021-12-14 19:39

          來源 | https://blog.bitsrc.io/5-common-mistakes-in-using-promises-bfcc4d62657f

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

          1、避免 Promise?回調(diào)地獄

          通常,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。當(dāng)我們在一個函數(shù)聲明前使用 async 關(guān)鍵字時,它會返回一個 Promise,我們可以使用 await 關(guān)鍵字來停止代碼,直到我們正在等待的Promise解決或拒絕。

          但是,當(dāng)你把一個 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); }})();

          當(dāng)我在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ù)中。然而,有些人可能會認(rèn)為只有在執(zhí)行myPromise 的then方法之后才被觸發(fā)。

          然而,真相并非如此。相反,當(dāng)一個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ù)是一種耗時的機制。只有當(dāng)開發(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');   })();

          本文完~



          1. JavaScript 重溫系列(22篇全)
          2. ECMAScript 重溫系列(10篇全)
          3. JavaScript設(shè)計模式 重溫系列(9篇全)
          4.?正則 / 框架 / 算法等 重溫系列(16篇全)
          5.?Webpack4 入門(上)||?Webpack4 入門(下)
          6.?MobX 入門(上)?||??MobX 入門(下)
          7. 120+篇原創(chuàng)系列匯總

          回復(fù)“加群”與大佬們一起交流學(xué)習(xí)~

          點擊“閱讀原文”查看 130+ 篇原創(chuàng)文章

          瀏覽 41
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚洲yw无码在线免费观看 | 日韩AⅤ视频 | 超碰在线香蕉 | 狠狠操视频网 | 国语对白精品 |