」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > JS:承諾還是回調?

JS:承諾還是回調?

發佈於2024-11-02
瀏覽:278

JS: Promise or Callback?

理解 JavaScript 中的 Promise 與 Callback

認證測驗的關鍵問題和解答

  1. 什麼是回呼函數,它與常規函數有何不同?

    • 回呼函數作為參數傳遞給另一個函數並被呼叫以處理非同步操作。與常規函數不同,回呼被設計為在完成某個任務後執行。
  2. 與回呼相比,Promise 如何提高程式碼可讀性並管理非同步操作?

    • Promise 允許連結和更好的錯誤處理,從而產生更具可讀性和可維護性的程式碼。它們有助於避免被稱為“回調地獄”的深層嵌套結構。
  3. Promise 的主要狀態是什麼,它們如何在這些狀態之間轉換?

    • 主要狀態有:Pending(初始狀態)、Fulfilled(操作成功完成)、Rejected(操作失敗)。 Promise 從 Pending 轉換為 Fulfilled 或 Rejected。
  4. 如何使用 Promises 處理錯誤,這與使用回呼的錯誤處理相比如何?

    • Promises 提供了一個 catch 方法來以簡化的方式處理錯誤,而使用回調進行錯誤處理通常需要傳遞錯誤物件並在嵌套回呼中進行多次檢查。
  5. Promise.all 和 Promise.race 有什麼區別,什麼時候使用它們?

    • Promise.all 在所有輸入 Promise 解析時解析,這使得它對等待多個非同步操作完成非常有用。一旦其中一個輸入 Promise 解析,Promise.race 就會解析,這對於需要第一個完成的操作結果的場景很有用。
  6. async/await 語法如何簡化 Promises 的使用,以及使用 wait 的規則是什麼?

    • async/await 語法允許以同步方式編寫非同步程式碼,提高可讀性。 wait 只能在非同步函數內部使用,並暫停執行直到 Promise 解析。

介紹

在 JavaScript 不斷發展的環境中,有效管理非同步操作是建立高效能 Web 應用程式的關鍵。雖然回調是最初的方法,但 Promises 引入了一種更結構化和可讀的方法來處理非同步任務。本部落格深入探討了使用 Promise 與回呼的複雜性,假設您已經對這些概念有基本的了解。

Promise 相對於回調的好處

提高可讀性和可維護性

回調雖然有效,但通常會導致稱為「回調地獄」的深層嵌套結構,使程式碼難以閱讀和維護。

回調地獄的例子:
fetchData(function(response1) {
  fetchMoreData(response1, function(response2) {
    fetchEvenMoreData(response2, function(response3) {
      console.log(response3);
    });
  });
});
透過 Promise 進行改進:
fetchData()
  .then(response1 => fetchMoreData(response1))
  .then(response2 => fetchEvenMoreData(response2))
  .then(response3 => console.log(response3))
  .catch(error => console.error(error));

錯誤處理

使用回調,錯誤處理可能會變得很麻煩,因為您需要傳遞錯誤物件並在每個層級處理它們。

使用回調處理錯誤:
function fetchData(callback) {
  setTimeout(() => {
    if (/* error condition */) {
      callback(new Error('An error occurred'), null);
    } else {
      callback(null, 'data');
    }
  }, 1000);
}

fetchData((error, data) => {
  if (error) {
    console.error(error);
  } else {
    console.log(data);
  }
});
使用 Promise 進行錯誤處理:
function fetchData() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (/* error condition */) {
        reject(new Error('An error occurred'));
      } else {
        resolve('data');
      }
    }, 1000);
  });
}

fetchData()
  .then(data => console.log(data))
  .catch(error => console.error(error));

高級 Promise 方法

Promise.all

當您需要等待多個非同步操作完成後再繼續操作時,Promise.all 非常有用。

例子:
const promise1 = Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, 'foo');
});

Promise.all([promise1, promise2, promise3]).then(values => {
  console.log(values); // [3, 42, "foo"]
});

Promise.race

當您需要最快操作的結果時,Promise.race 很有用。

例子:
const promise1 = new Promise((resolve, reject) => {
  setTimeout(resolve, 500, 'one');
});

const promise2 = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, 'two');
});

Promise.race([promise1, promise2]).then(value => {
  console.log(value); // "two"
});

使用 async/await 簡化非同步程式碼

async/await 語法可讓您編寫看起來同步的非同步程式碼,增強可讀性並降低連結 Promise 的複雜性。

例子:
async function fetchData() {
  return 'data';
}

async function processData() {
  try {
    const data = await fetchData();
    console.log(data);
  } catch (error) {
    console.error(error);
  }
}

processData();

結論

雖然回調為 JavaScript 中處理非同步操作奠定了基礎,但 Promise 顯著提高了非同步程式碼的可讀性、可維護性和錯誤處理能力。了解如何以及何時有效地使用這些工具對於現代 JavaScript 開發至關重要。借助 Promises 和 async/await 語法,開發人員可以編寫更清晰、更易於管理的程式碼,為更強大的應用程式鋪平道路。

版本聲明 本文轉載於:https://dev.to/dariansdev/js-promise-or-callback-704?1如有侵犯,請聯絡[email protected]刪除
最新教學 更多>
  • 為什麼HTML無法打印頁碼及解決方案
    為什麼HTML無法打印頁碼及解決方案
    無法在html頁面上打印頁碼? @page規則在@Media內部和外部都無濟於事。 HTML:Customization:@page { margin: 10%; @top-center { font-family: sans-serif; font-weight: ...
    程式設計 發佈於2025-05-05
  • 為什麼我在Silverlight Linq查詢中獲得“無法找到查詢模式的實現”錯誤?
    為什麼我在Silverlight Linq查詢中獲得“無法找到查詢模式的實現”錯誤?
    查詢模式實現缺失:解決“無法找到”錯誤在Silverlight應用程序中,嘗試使用LINQ建立LINQ連接以錯誤而實現的數據庫”,無法找到查詢模式的實現。”當省略LINQ名稱空間或查詢類型缺少IEnumerable 實現時,通常會發生此錯誤。 解決問題來驗證該類型的質量是至關重要的。在此特定實例...
    程式設計 發佈於2025-05-05
  • 為什麼我會收到MySQL錯誤#1089:錯誤的前綴密鑰?
    為什麼我會收到MySQL錯誤#1089:錯誤的前綴密鑰?
    mySQL錯誤#1089:錯誤的前綴鍵錯誤descript [#1089-不正確的前綴鍵在嘗試在表中創建一個prefix鍵時會出現。前綴鍵旨在索引字符串列的特定前綴長度長度,以便更快地搜索這些前綴。 理解prefix keys `這將在整個Movie_ID列上創建標準主鍵。主密鑰對於唯一識...
    程式設計 發佈於2025-05-05
  • C++成員函數指針正確傳遞方法
    C++成員函數指針正確傳遞方法
    如何將成員函數置於c 的函數時,接受成員函數指針的函數時,必須同時提供對象的指針,並提供指針和指針到函數。需要具有一定簽名的功能指針。要通過成員函數,您需要同時提供對象指針(此)和成員函數指針。這可以通過修改Menubutton :: SetButton()(如下所示:[&& && && &&華)...
    程式設計 發佈於2025-05-05
  • 在細胞編輯後,如何維護自定義的JTable細胞渲染?
    在細胞編輯後,如何維護自定義的JTable細胞渲染?
    在JTable中維護jtable單元格渲染後,在JTable中,在JTable中實現自定義單元格渲染和編輯功能可以增強用戶體驗。但是,至關重要的是要確保即使在編輯操作後也保留所需的格式。 在設置用於格式化“價格”列的“價格”列,用戶遇到的數字格式丟失的“價格”列的“價格”之後,問題在設置自定義單元...
    程式設計 發佈於2025-05-05
  • Python不會對超範圍子串切片報錯的原因
    Python不會對超範圍子串切片報錯的原因
    在python中用索引切片範圍:二重性和空序列索引單個元素不同,該元素會引起錯誤,切片在序列的邊界之外沒有。 這種行為源於索引和切片之間的基本差異。索引一個序列,例如“示例” [3],返回一個項目。但是,切片序列(例如“示例” [3:4])返回項目的子序列。 索引不存在的元素時,例如“示例” [9...
    程式設計 發佈於2025-05-05
  • 在Oracle SQL中如何提取下劃線前的子字符串?
    在Oracle SQL中如何提取下劃線前的子字符串?
    [ 在oracle sql 解決方案: Explanation:SUBSTR function extracts a substring starting from the specified position (0) and continuing for a specified length.IN...
    程式設計 發佈於2025-05-05
  • 如何使用組在MySQL中旋轉數據?
    如何使用組在MySQL中旋轉數據?
    在關係數據庫中使用mySQL組使用mySQL組進行查詢結果,在關係數據庫中使用MySQL組,轉移數據的數據是指重新排列的行和列的重排以增強數據可視化。在這裡,我們面對一個共同的挑戰:使用組的組將數據從基於行的基於列的轉換為基於列。 Let's consider the following ...
    程式設計 發佈於2025-05-05
  • 如何在GO編譯器中自定義編譯優化?
    如何在GO編譯器中自定義編譯優化?
    在GO編譯器中自定義編譯優化 GO中的默認編譯過程遵循特定的優化策略。 However, users may need to adjust these optimizations for specific requirements.Optimization Control in Go Compi...
    程式設計 發佈於2025-05-05
  • `console.log`顯示修改後對象值異常的原因
    `console.log`顯示修改後對象值異常的原因
    foo = [{id:1},{id:2},{id:3},{id:4},{id:id:5},],]; console.log('foo1',foo,foo.length); foo.splice(2,1); console.log('foo2', foo, foo....
    程式設計 發佈於2025-05-05
  • 如何在其容器中為DIV創建平滑的左右CSS動畫?
    如何在其容器中為DIV創建平滑的左右CSS動畫?
    通用CSS動畫,用於左右運動 ,我們將探索創建一個通用的CSS動畫,以向左和右移動DIV,從而到達其容器的邊緣。該動畫可以應用於具有絕對定位的任何div,無論其未知長度如何。 問題:使用左直接導致瞬時消失 更加流暢的解決方案:混合轉換和左 [並實現平穩的,線性的運動,我們介紹了線性的轉換。...
    程式設計 發佈於2025-05-05
  • 如何使用Python有效地以相反順序讀取大型文件?
    如何使用Python有效地以相反順序讀取大型文件?
    在python 反向行讀取器生成器 == ord('\ n'): 緩衝區=緩衝區[:-1] 剩餘_size- = buf_size lines = buffer.split('\ n'....
    程式設計 發佈於2025-05-05
  • 如何有效地轉換PHP中的時區?
    如何有效地轉換PHP中的時區?
    在PHP 利用dateTime對象和functions DateTime對象及其相應的功能別名為時區轉換提供方便的方法。例如: //定義用戶的時區 date_default_timezone_set('歐洲/倫敦'); //創建DateTime對象 $ dateTime = ne...
    程式設計 發佈於2025-05-05
  • 如何解決由於Android的內容安全策略而拒絕加載腳本... \”錯誤?
    如何解決由於Android的內容安全策略而拒絕加載腳本... \”錯誤?
    Unveiling the Mystery: Content Security Policy Directive ErrorsEncountering the enigmatic error "Refused to load the script..." when deployi...
    程式設計 發佈於2025-05-05

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3