精品熟人妻一区二区三区四区不卡-精品爽黄69天堂a-精品水蜜桃久久久久久久-精品丝袜国产自在线拍-精品丝袜国产自在线拍a-精品丝袜国产自在线拍免费看

LOGO OA教程 ERP教程 模切知識(shí)交流 PMS教程 CRM教程 開(kāi)發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

JS函數(shù)回調(diào)的本質(zhì)原理和應(yīng)用場(chǎng)景

freeflydom
2025年4月10日 12:1 本文熱度 657

函數(shù)回調(diào)的定義:
通俗地講,把一個(gè)函數(shù)作為參數(shù)傳給另一個(gè)函數(shù),這個(gè)函數(shù)則稱(chēng)為回調(diào)函數(shù)。

圖解:
正常函數(shù)的模型圖

函數(shù)回調(diào)的模型圖

在看看嚴(yán)格點(diǎn)的定義:
函數(shù)回調(diào)就是一個(gè)通過(guò)函數(shù)指針調(diào)用的函數(shù)。如果你把函數(shù)的指針(地址)作為參數(shù)傳遞給另一個(gè)函數(shù),當(dāng)這個(gè)指針被用來(lái)調(diào)用其所指向的函數(shù)時(shí),我們就說(shuō)這是回調(diào)函數(shù)。回調(diào)函數(shù)不是由該函數(shù)的實(shí)現(xiàn)方直接調(diào)用,而是在特定的事件或條件發(fā)生時(shí)由另外的一方調(diào)用的,用于對(duì)該事件或條件進(jìn)行響應(yīng)。(新人可能會(huì)云里霧里,沒(méi)關(guān)系,結(jié)合著案例多看看。)

下文的函數(shù)回調(diào)、回調(diào)函數(shù)是一個(gè)意思。


把函數(shù)當(dāng)參數(shù)

把函數(shù)當(dāng)做參數(shù)的好處是?
假設(shè)實(shí)現(xiàn)一個(gè)計(jì)算器的需求,先編寫(xiě)三個(gè)功能函數(shù):求兩個(gè)整數(shù)的求最大值,求最小值,求和。

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("請(qǐng)輸入整數(shù)a:")
    b = input("請(qǐng)輸入整數(shù)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)
請(qǐng)輸入整數(shù)a:2
請(qǐng)輸入整數(shù)b:3
Max of 2 and 3 is 3
Min of 2 and 3 is 2
Sum of 2 and 3 is 5

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

在調(diào)用max、min、sum時(shí),這三個(gè)函數(shù)就是此處的回調(diào)函數(shù)。(回調(diào)函數(shù)和普通函數(shù)在定義的時(shí)候沒(méi)有什么區(qū)別,只有在調(diào)用時(shí)才看出來(lái)是不是回調(diào)函數(shù),正常調(diào)用就是普通函數(shù),作為一個(gè)函數(shù)的參數(shù)在需要的時(shí)候分情況調(diào)用,就是回調(diào)函數(shù)。)


可以異步的函數(shù)

當(dāng)然回調(diào)函數(shù)還有一個(gè)更大的作用,就是可以結(jié)合上下文做異步,好處是異步不阻塞

需要說(shuō)明一下,回調(diào)的異步性并非來(lái)自函數(shù)本身,而是由調(diào)用它的API或操作(如setTimeout、I/O、事件監(jiān)聽(tīng))決定的。這種設(shè)計(jì)使得程序能在等待耗時(shí)操作時(shí)不阻塞主線程,從而提升效率和用戶(hù)體驗(yàn)。

異步是系統(tǒng)底層封裝好的功能,大致是通過(guò)對(duì)事件循環(huán)和任務(wù)隊(duì)列機(jī)制等一起打包好了,只暴露一些公開(kāi)函數(shù)和關(guān)鍵字給使用者。使用者只需要設(shè)計(jì)好一個(gè)代碼塊、一個(gè)函數(shù)傳入異步即可,所以函數(shù)回調(diào)和異步就這樣結(jié)合起來(lái)了。

異步不是本文的核心,這里只看看回調(diào)怎么結(jié)合異步實(shí)現(xiàn)一些超越同步編程的效果就好。

異步在前端編程中很常用,下面通過(guò)一個(gè)前端開(kāi)發(fā)場(chǎng)景來(lái)展示異步回調(diào)如何解決同步代碼無(wú)法處理的問(wèn)題:避免界面凍結(jié),同時(shí)執(zhí)行耗時(shí)任務(wù)


案例背景:模擬文件上傳

假設(shè)我們正在開(kāi)發(fā)一個(gè)網(wǎng)頁(yè),用戶(hù)點(diǎn)擊按鈕后需要:

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

同步代碼的問(wèn)題

如果用同步代碼實(shí)現(xiàn)文件上傳,會(huì)阻塞主線程,導(dǎo)致界面完全卡死,用戶(hù)無(wú)法進(jìn)行任何操作:

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

問(wèn)題

  • 上傳期間,用戶(hù)無(wú)法在輸入框打字,所有UI操作被凍結(jié)。
  • 控制臺(tái)輸出順序是:
    開(kāi)始上傳...
    (3秒后)
    上傳成功
    

異步回調(diào)解決方案

改用異步回調(diào),釋放主線程,讓用戶(hù)在上傳過(guò)程中繼續(xù)操作頁(yè)面:

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

關(guān)鍵區(qū)別

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

流程圖解

[用戶(hù)點(diǎn)擊上傳按鈕]
│
├─ 主線程執(zhí)行:調(diào)用 uploadAsync
│  │
│  ├─ 1. 輸出 "開(kāi)始上傳..."
│  │
│  ├─ 2. 啟動(dòng)異步操作(setTimeout 3秒)
│  │   │
│  │   └─ (3秒后)執(zhí)行回調(diào):更新界面狀態(tài)
│  │
│  └─ 3. 函數(shù)立即返回,主線程空閑
│
├─ 用戶(hù)立即可以操作頁(yè)面(輸入文字、點(diǎn)擊其他按鈕)
│
└─ 3秒后,回調(diào)觸發(fā),更新界面

為什么異步回調(diào)解決了同步無(wú)法處理的問(wèn)題?

  1. 非阻塞主線程

    • 同步代碼會(huì)獨(dú)占主線程,導(dǎo)致瀏覽器無(wú)法處理用戶(hù)輸入、動(dòng)畫(huà)渲染等任務(wù)。
    • 異步回調(diào)將耗時(shí)任務(wù)交給瀏覽器底層API(如網(wǎng)絡(luò)線程、定時(shí)器線程),主線程繼續(xù)響應(yīng)用戶(hù)操作。
  2. 保持用戶(hù)體驗(yàn)

    • 用戶(hù)在上傳文件時(shí),仍可以與其他UI元素交互(如填寫(xiě)表單、切換標(biāo)簽頁(yè))。
  3. 真實(shí)場(chǎng)景應(yīng)用

    • 所有Web應(yīng)用的網(wǎng)絡(luò)請(qǐng)求(如AJAX、Fetch API)、文件讀寫(xiě)(Node.js)、數(shù)據(jù)庫(kù)操作都必須使用異步,否則會(huì)導(dǎo)致服務(wù)完全卡死。

實(shí)際開(kāi)發(fā)中會(huì)用到的異步回調(diào)

真實(shí)項(xiàng)目中,異步回調(diào)常用于:

// 1. 網(wǎng)絡(luò)請(qǐng)求
fetch("/api/data")
  .then(response => response.json())
  .then(data => console.log(data));
// 2. 定時(shí)任務(wù)
setTimeout(() => console.log("延時(shí)操作"), 1000);
// 3. 用戶(hù)事件監(jiān)聽(tīng)
document.getElementById("button").addEventListener("click", () => {
  console.log("按鈕被點(diǎn)擊");
});
// 4. Node.js 文件讀取
const fs = require("fs");
fs.readFile("file.txt", "utf8", (err, data) => {
  if (err) throw err;
  console.log(data);
});

以上場(chǎng)景一般也都是 回調(diào)函數(shù) + 異步實(shí)現(xiàn)。


總結(jié)

  • 同步代碼的問(wèn)題:阻塞主線程,導(dǎo)致界面凍結(jié)、用戶(hù)體驗(yàn)極差。
  • 異步回調(diào)的優(yōu)勢(shì)
    • 主線程保持響應(yīng),用戶(hù)可以繼續(xù)操作。
    • 充分利用硬件資源(如多線程、非阻塞I/O)。
    • 適用于所有耗時(shí)操作(網(wǎng)絡(luò)、I/O、復(fù)雜計(jì)算)。

這也是現(xiàn)代Web開(kāi)發(fā)中,異步回調(diào)(及其衍生技術(shù)如Promise、Async/Await)是必須掌握的核心概念!

轉(zhuǎn)自https://www.cnblogs.com/mysticbinary/p/18814975


該文章在 2025/4/10 12:01:19 編輯過(guò)
關(guān)鍵字查詢(xún)
相關(guān)文章
正在查詢(xún)...
點(diǎn)晴ERP是一款針對(duì)中小制造業(yè)的專(zhuān)業(yè)生產(chǎn)管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國(guó)內(nèi)大量中小企業(yè)的青睞。
點(diǎn)晴PMS碼頭管理系統(tǒng)主要針對(duì)港口碼頭集裝箱與散貨日常運(yùn)作、調(diào)度、堆場(chǎng)、車(chē)隊(duì)、財(cái)務(wù)費(fèi)用、相關(guān)報(bào)表等業(yè)務(wù)管理,結(jié)合碼頭的業(yè)務(wù)特點(diǎn),圍繞調(diào)度、堆場(chǎng)作業(yè)而開(kāi)發(fā)的。集技術(shù)的先進(jìn)性、管理的有效性于一體,是物流碼頭及其他港口類(lèi)企業(yè)的高效ERP管理信息系統(tǒng)。
點(diǎn)晴WMS倉(cāng)儲(chǔ)管理系統(tǒng)提供了貨物產(chǎn)品管理,銷(xiāo)售管理,采購(gòu)管理,倉(cāng)儲(chǔ)管理,倉(cāng)庫(kù)管理,保質(zhì)期管理,貨位管理,庫(kù)位管理,生產(chǎn)管理,WMS管理系統(tǒng),標(biāo)簽打印,條形碼,二維碼管理,批號(hào)管理軟件。
點(diǎn)晴免費(fèi)OA是一款軟件和通用服務(wù)都免費(fèi),不限功能、不限時(shí)間、不限用戶(hù)的免費(fèi)OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved

主站蜘蛛池模板: 国产精品成人99一区无码 | 日本精品 | 在线首页av免费观看 | 久久不见久久见免费影院www日本 | 亚洲视频一 | 麻豆久久| 亚洲日产?v中文字幕无码偷拍 | 91麻豆精品国产 | 成全视频在线观看在线 | 人人妻人人藻人人爽欧美一区 | 欧洲熟妇色 | 国产主播一区二区三区在线观看 | 无码aⅴ精品一区二区三区浪潮 | 成人蕾丝电影在线播放网站 | 无码a√毛片一区二区三区 无码aⅴ精 | 久草超碰在线 | 亚洲成a人片在线v | 99999久久久久久亚洲 | 91视频精品 | 国产a一级无码毛片一区二区三区 | 在线播放免费人成毛片乱码 | 欧美一区区 | 欧美性xxxxx极 | 天天做日日做天天添天天欢公交 | 日韩一区二区三区久久久 | 99re热这里只有精品视频 | 亚洲av无码电影在线播放 | 99re热视频这里只精品 | 99久久www免费人成精品 | 国自产精品手机在线观看视 | 日韩在线欧美精品一区二区 | 麻豆91欧美国产亚洲 | 好吊色欧美一区二区三区四区 | 亚洲欧美人成综合导航 | 精品久久久久久无码国产 | 东京热一区二区三区无码视频 | 国产无套码aⅴ在线观看在 国产无套内射又大又 | 丰满少妇被猛男进入高清播放 | 香蕉视频在线久久 | 成人精品在线观看 | 在线极品美女a毛片费观看 在线精品91青草国产 |