<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12


      函數回調的定義:
      通俗地講,把一個函數作為參數傳給另一個函數,這個函數則稱為回調函數。

      圖解:
      正常函數的模型圖
      image

      函數回調的模型圖
      image

      在看看嚴格點的定義:
      函數回調就是一個通過函數指針調用的函數。如果你把函數的指針(地址)作為參數傳遞給另一個函數,當這個指針被用來調用其所指向的函數時,我們就說這是回調函數。回調函數不是由該函數的實現方直接調用,而是在特定的事件或條件發生時由另外的一方調用的,用于對該事件或條件進行響應。(新人可能會云里霧里,沒關系,結合著案例多看看。)

      下文的函數回調、回調函數是一個意思。


      把函數當參數

      把函數當做參數的好處是?
      假設實現一個計算器的需求,先編寫三個功能函數:求兩個整數的求最大值,求最小值,求和。

      def computer(a, b, func):
          return func(a, b)
      
      
      def max(a, b):
          return [a, b][a < b]
      
      
      def min(a, b):
          return [a, b][a > b]
      
      
      def sum(a, b):
          return str(int(a) + int(b))
      
      
      if __name__ == "__main__":
          a = input("請輸入整數a:")
          b = input("請輸入整數b:")
      
          res = computer(a, b, max)
          print("Max of " + a + " and " + b + " is " + res)
      
          res = computer(a, b, min)
          print("Min of " + a + " and " + b + " is " + res)
      
          res = computer(a, b, sum)
          print("Sum of " + a + " and " + b + " is " + res)
      
      
      請輸入整數a:2
      請輸入整數b:3
      Max of 2 and 3 is 3
      Min of 2 and 3 is 2
      Sum of 2 and 3 is 5
      

      但是這個包將作為SDK給別人使用的話,是不知道別人想搭配什么功能函數的。那么可以將這三個函數都作為實參,讓用戶自由傳入,這樣就增加了編程的靈活性

      在調用max、min、sum時,這三個函數就是此處的回調函數。(回調函數和普通函數在定義的時候沒有什么區別,只有在調用時才看出來是不是回調函數,正常調用就是普通函數,作為一個函數的參數在需要的時候分情況調用,就是回調函數。)


      可以異步的函數

      當然回調函數還有一個更大的作用,就是可以結合上下文做異步,好處是異步不阻塞

      需要說明一下,回調的異步性并非來自函數本身,而是由調用它的API或操作(如setTimeout、I/O、事件監聽)決定的。這種設計使得程序能在等待耗時操作時不阻塞主線程,從而提升效率和用戶體驗。

      異步是系統底層封裝好的功能,大致是通過對事件循環和任務隊列機制等一起打包好了,只暴露一些公開函數和關鍵字給使用者。使用者只需要設計好一個代碼塊一個函數傳入異步即可,所以函數回調和異步就這樣結合起來了。

      異步不是本文的核心,這里只看看回調怎么結合異步實現一些超越同步編程的效果就好。

      異步在前端編程中很常用,下面通過一個前端開發場景來展示異步回調如何解決同步代碼無法處理的問題:避免界面凍結,同時執行耗時任務


      案例背景:模擬文件上傳

      假設我們正在開發一個網頁,用戶點擊按鈕后需要:

      1. 上傳一個大文件到服務器(耗時操作)。
      2. 上傳完成后顯示“上傳成功”。
      3. 同時,用戶在上傳過程中可以繼續操作頁面(比如輸入文字、點擊其他按鈕)。

      同步代碼的問題

      如果用同步代碼實現文件上傳,會阻塞主線程,導致界面完全卡死,用戶無法進行任何操作:

      // 同步上傳函數(假設存在同步的 uploadSync API)
      function uploadSync(file) {
        // 模擬耗時操作(假設上傳需要3秒)
        const start = Date.now();
        while (Date.now() - start < 3000) {} // 同步阻塞3秒
        return "上傳成功";
      }
      
      // 點擊按鈕觸發上傳
      document.getElementById("uploadBtn").addEventListener("click", () => {
        console.log("開始上傳...");
        const result = uploadSync("bigfile.zip"); // 同步調用,阻塞主線程3秒
        console.log(result);
        document.getElementById("status").textContent = result;
      });
      
      // 用戶嘗試在上傳過程中輸入文字,但界面會卡住3秒!
      

      問題

      • 上傳期間,用戶無法在輸入框打字,所有UI操作被凍結。
      • 控制臺輸出順序是:
        開始上傳...
        (3秒后)
        上傳成功
        

      異步回調解決方案

      改用異步回調,釋放主線程,讓用戶在上傳過程中繼續操作頁面:

      // 異步上傳函數(使用回調)
      function uploadAsync(file, callback) {
        console.log("開始上傳...");
        // 使用 setTimeout 模擬異步上傳(如真實的 fetch 或 XMLHttpRequest)
        setTimeout(() => {
          const result = "上傳成功";
          callback(result); // 上傳完成后調用回調
        }, 3000);
      }
      
      // 點擊按鈕觸發上傳
      document.getElementById("uploadBtn").addEventListener("click", () => {
        uploadAsync("bigfile.zip", (result) => {
          console.log(result);
          document.getElementById("status").textContent = result;
        });
      });
      
      // 用戶可以在上傳過程中正常輸入文字!
      
      setTimeout()函數介紹:函數接受兩個參數,第一個是回調函數,第二個是推遲執行的毫秒數。
      
      setTimeout()會將事件插入了"任務隊列",必須等到當前代碼(執行棧)執行完,主線程才會去執行它指定的回調函數。 要是當前代碼耗時很長,有可能要等很久,所以并沒有辦法保證,回調函數一定會在setTimeout()指定的時間執行。
      

      關鍵區別

      • 上傳期間,用戶可以在輸入框自由輸入,界面保持響應。
      • 控制臺輸出順序是:
        開始上傳...
        (立即輸出,不阻塞)
        (3秒后)
        上傳成功
        

      流程圖解

      [用戶點擊上傳按鈕]
      │
      ├─ 主線程執行:調用 uploadAsync
      │  │
      │  ├─ 1. 輸出 "開始上傳..."
      │  │
      │  ├─ 2. 啟動異步操作(setTimeout 3秒)
      │  │   │
      │  │   └─ (3秒后)執行回調:更新界面狀態
      │  │
      │  └─ 3. 函數立即返回,主線程空閑
      │
      ├─ 用戶立即可以操作頁面(輸入文字、點擊其他按鈕)
      │
      └─ 3秒后,回調觸發,更新界面
      

      為什么異步回調解決了同步無法處理的問題?

      1. 非阻塞主線程

        • 同步代碼會獨占主線程,導致瀏覽器無法處理用戶輸入、動畫渲染等任務。
        • 異步回調將耗時任務交給瀏覽器底層API(如網絡線程、定時器線程),主線程繼續響應用戶操作。
      2. 保持用戶體驗

        • 用戶在上傳文件時,仍可以與其他UI元素交互(如填寫表單、切換標簽頁)。
      3. 真實場景應用

        • 所有Web應用的網絡請求(如AJAX、Fetch API)、文件讀寫(Node.js)、數據庫操作都必須使用異步,否則會導致服務完全卡死。

      實際開發中會用到的異步回調

      真實項目中,異步回調常用于:

      // 1. 網絡請求
      fetch("/api/data")
        .then(response => response.json())
        .then(data => console.log(data));
      
      // 2. 定時任務
      setTimeout(() => console.log("延時操作"), 1000);
      
      // 3. 用戶事件監聽
      document.getElementById("button").addEventListener("click", () => {
        console.log("按鈕被點擊");
      });
      
      // 4. Node.js 文件讀取
      const fs = require("fs");
      fs.readFile("file.txt", "utf8", (err, data) => {
        if (err) throw err;
        console.log(data);
      });
      

      以上場景一般也都是 回調函數 + 異步實現。


      總結

      • 同步代碼的問題:阻塞主線程,導致界面凍結、用戶體驗極差。
      • 異步回調的優勢
        • 主線程保持響應,用戶可以繼續操作。
        • 充分利用硬件資源(如多線程、非阻塞I/O)。
        • 適用于所有耗時操作(網絡、I/O、復雜計算)。

      這也是現代Web開發中,異步回調(及其衍生技術如Promise、Async/Await)是必須掌握的核心概念!

      有興趣的同學,可以更深入地研究一下系統底層都做了什么,才能達成異步效果。 Bye !

      posted on 2025-04-09 11:09  Mysticbinary  閱讀(486)  評論(0)    收藏  舉報



      主站蜘蛛池模板: 无码精品国产VA在线观看DVD| 开心婷婷五月激情综合社区 | 丰满的少妇一区二区三区| 亚洲熟妇自偷自拍另亚洲| 又大又粗又硬又爽黄毛少妇 | 无码少妇一区二区| 国产成人片无码视频| 久久精品国产99精品亚洲| 九九成人免费视频| 无码伊人66久久大杳蕉网站谷歌| 亚洲乱熟乱熟女一区二区| 日韩全网av在线| 国内精品一区二区不卡| 激情综合五月| 在线观看无码不卡av| 国产精品天天看天天狠| 久久精品国产亚洲av品| 国产欧美日韩亚洲一区二区三区| 人妻中文字幕精品系列| 亚洲区中文字幕日韩精品| 神马午夜久久精品人妻| 精品无码国产不卡在线观看| 亚洲国产大胸一区二区三区 | 巴林右旗| 高清免费毛片| 免费看久久妇女高潮a| 亚洲精品一区二区口爆| 日韩丝袜亚洲国产欧美一区| 国产亚洲午夜高清国产拍精品| 色欲综合久久中文字幕网| 亚洲午夜久久久久久噜噜噜 | 国产中年熟女高潮大集合| 91亚洲国产成人精品性色| h无码精品3d动漫在线观看| 少妇午夜啪爽嗷嗷叫视频| 亚洲国产综合av在线观看| 国产亚洲精品成人aa片新蒲金| 人妻互换一二三区激情视频 | 国产AV国片精品有毛| 亚洲人成网线在线播放VA | 国产亚洲精品AA片在线播放天|