您好,登錄后才能下訂單哦!
這篇文章主要介紹了JavaScript中的回調函數是什么,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
回調函數是每個前端程序員都應該知道的概念之一。回調可用于數組、計時器函數、promise、事件處理中。
首先寫一個向人打招呼的函數。
只需要創建一個接受 name
參數的函數 greet(name)
。這個函數應返回打招呼的消息:
function greet(name) { return `Hello, ${name}!`; } greet('Cristina'); // => 'Hello, Cristina!'
如果向很多人打招呼該怎么辦?可以用特殊的數組方法 array.map()
可以實現:
const persons = ['Cristina', 'Ana']; const messages = persons.map(greet); messages; // => ['Hello, Cristina!', 'Hello, Ana!']
persons.map(greet)
獲取 persons
數組的所有元素,并分別用每個元素作為調用參數來調用 greet()
函數:`greet('Cristina')
, greet('Ana')
。
有意思的是 persons.map(greet)
方法可以接受 greet()
函數作為參數。這樣 greet()
就成了回調函數。
persons.map(greet)
是用另一個函數作為參數的函數,因此被稱為高階函數。
回調函數作為高階函數的參數,高階函數通過調用回調函數來執行操作。
重要的是高階函數負責調用回調,并為其提供正確的參數。
在前面的例子中,高階函數 persons.map(greet)
負責調用 greet()
函數,并分別把數組中所有的元素 'Cristina'
和 Ana '
作為參數。
這就為識別回調提供了一條簡單的規則。如果你定義了一個函數,并將其作參數提供給另一個函數的話,那么這就創建了一個回調。
你可以自己編寫使用回調的高階函數。下面是 array.map()
方法的等效版本:
function map(array, callback) { const mappedArray = []; for (const item of array) { mappedArray.push( callback(item) ); } return mappedArray; } function greet(name) { return `Hello, ${name}!`; } const persons = ['Cristina', 'Ana']; const messages = map(persons, greet);messages; // => ['Hello, Cristina!', 'Hello, Ana!']
map(array, callback)
是一個高階函數,因為它用回調函數作為參數,然后在其主體內部調用該回調函數:callback(item)
。
注意,常規函數(用關鍵字 function
定義)或箭頭函數(用粗箭頭 =>
定義)同樣可以作為回調使用。
回調的調用方式有兩種:同步和異步回調。
同步回調是“阻塞”的:高階函數直到回調函數完成后才繼續執行。
例如,調用 map()
和 greet()
函數。
function map(array, callback) { console.log('map() starts'); const mappedArray = []; for (const item of array) { mappedArray.push(callback(item)) } console.log('map() completed'); return mappedArray; } function greet(name) { console.log('greet() called'); return `Hello, ${name}!`; } const persons = ['Cristina']; map(persons, greet); // logs 'map() starts' // logs 'greet() called' // logs 'map() completed'
其中 greet()
是同步回調。
同步回調的步驟:
高階函數開始執行:'map() starts'
回調函數執行:'greet() called'
.最后高階函數完成它自己的執行過程:'map() completed'
許多原生 JavaScript 類型的方法都使用同步回調。
最常用的是 array 的方法,例如: array.map(callback)
, array.forEach(callback)
, array.find(callback)
, array.filter(callback)
, array.reduce(callback, init)
// Examples of synchronous callbacks on arrays const persons = ['Ana', 'Elena']; persons.forEach( function callback(name) { console.log(name); } ); // logs 'Ana' // logs 'Elena' const nameStartingA = persons.find( function callback(name) { return name[0].toLowerCase() === 'a'; } ); nameStartingA; // => 'Ana' const countStartingA = persons.reduce( function callback(count, name) { const startsA = name[0].toLowerCase() === 'a'; return startsA ? count + 1 : count; }, 0 ); countStartingA; // => 1
字符串類型的 string.replace(callback)
方法也能接受同步執行的回調:
// Examples of synchronous callbacks on strings const person = 'Cristina'; // Replace 'i' with '1' person.replace(/./g, function(char) { return char.toLowerCase() === 'i' ? '1' : char; } ); // => 'Cr1st1na'
異步回調是“非阻塞的”:高階函數無需等待回調完成即可完成其執行。高階函數可確保稍后在特定事件上執行回調。
在以下的例子中,later()
函數的執行延遲了 2 秒:
console.log('setTimeout() starts'); setTimeout(function later() { console.log('later() called'); }, 2000); console.log('setTimeout() completed'); // logs 'setTimeout() starts' // logs 'setTimeout() completed' // logs 'later() called' (after 2 seconds)
later()
是一個異步回調,因為 setTimeout(later,2000)
啟動并完成了執行,但是 later()
在 2 秒后執行。
異步調用回調的步驟:
高階函數開始執行:'setTimeout()starts'
高階函數完成其執行: 'setTimeout() completed'
回調函數在 2 秒鐘后執行: 'later() called'
計時器函數異步調用回調:
setTimeout(function later() { console.log('2 seconds have passed!'); }, 2000); // After 2 seconds logs '2 seconds have passed!' setInterval(function repeat() { console.log('Every 2 seconds'); }, 2000); // Each 2 seconds logs 'Every 2 seconds!'
DOM 事件偵聽器還異步調用事件處理函數(回調函數的子類型):
const myButton = document.getElementById('myButton'); myButton.addEventListener('click', function handler() { console.log('Button clicked!'); }); // Logs 'Button clicked!' when the button is clicked
在函數定義之前加上特殊關鍵字 async
會創建一個異步函數:
async function fetchUserNames() { const resp = await fetch('https://api.github.com/users?per_page=5'); const users = await resp.json(); const names = users.map(({ login }) => login); console.log(names); }
fetchUserNames()
是異步的,因為它以 async
為前綴。函數 await fetch('https://api.github.com/users?per_page=5')
從 GitHub 上獲取前5個用戶 。然后從響應對象中提取 JSON 數據:await resp.json()
。
異步函數是 promise 之上的語法糖。當遇到表達式 await <promise>
(調用 fetch()
會返回一個promise)時,異步函數會暫停執行,直到 promise 被解決。
異步回調函數和異步函數是不同的兩個術語。
異步回調函數由高階函數以非阻塞方式執行。但是異步函數在等待 promise(await <promise>
)解析時會暫停執行。
但是你可以把異步函數用作異步回調!
讓我們把異步函數 fetch UserNames()
設為異步回調,只需單擊按鈕即可調用:
const button = document.getElementById('fetchUsersButton'); button.addEventListener('click', fetchUserNames);
感謝你能夠認真閱讀完這篇文章,希望小編分享的“JavaScript中的回調函數是什么”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。