国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

node.js|vue.js|jquery|angularjs|React|json|js教程|

服務器之家 - 編程語言 - JavaScript - js教程 - 一篇文章看懂JavaScript中的回調

一篇文章看懂JavaScript中的回調

2021-12-27 15:59瘋狂的技術宅 js教程

這篇文章主要給大家介紹了如何通過一篇文章看懂JavaScript中的回調,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

前言

回調函數是每個前端程序員都應該知道的概念之一。回調可用于數組、計時器函數、promise、事件處理中。

本文將會解釋回調函數的概念,同時幫你區分兩種回調:同步和異步。

回調函數

首先寫一個向人打招呼的函數。

只需要創建一個接受 name 參數的函數 greet(name)。這個函數應返回打招呼的消息:

?
1
2
3
4
5
function greet(name) {
 return `Hello, ${name}!`;
}
 
greet('Cristina'); // => 'Hello, Cristina!'

如果向很多人打招呼該怎么辦?可以用特殊的數組方法  array.map() 可以實現:

?
1
2
3
4
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() 方法的等效版本:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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() 函數。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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()  是同步回調。

同步回調的步驟:

  1. 高階函數開始執行:'map() starts'
  2. 回調函數執行:'greet() called'
  3. .最后高階函數完成它自己的執行過程:'map() completed'

同步回調的例子

許多原生 JavaScript 類型的方法都使用同步回調。

最常用的是 array 的方法,例如:array.map(callback), array.forEach(callback), array.find(callback), array.filter(callback), array.reduce(callback, init)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 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)  方法也能接受同步執行的回調:

?
1
2
3
4
5
6
7
8
// 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 秒:

?
1
2
3
4
5
6
7
8
9
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 秒后執行。

異步調用回調的步驟:

  1. 高階函數開始執行:'setTimeout()starts'
  2. 高階函數完成其執行:'setTimeout() completed'
  3. 回調函數在 2 秒鐘后執行:'later() called'

異步回調的例子

計時器函數異步調用回調:

?
1
2
3
4
5
6
7
8
9
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 事件偵聽器還異步調用事件處理函數(回調函數的子類型):

?
1
2
3
4
5
6
const myButton = document.getElementById('myButton');
 
myButton.addEventListener('click', function handler() {
 console.log('Button clicked!');
});
// Logs 'Button clicked!' when the button is clicked

4.異步回調函數與異步函數

在函數定義之前加上特殊關鍵字 async 會創建一個異步函數:

?
1
2
3
4
5
6
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() 設為異步回調,只需單擊按鈕即可調用:

?
1
2
3
const button = document.getElementById('fetchUsersButton');
 
button.addEventListener('click', fetchUserNames);

總結

回調是一個可以作為參數傳給另一個函數(高階函數)執行的函數。

回調函數有兩種:同步和異步。

同步回調是阻塞的。

異步回調是非阻塞的。

最后考考你:setTimeout(callback,0) 執行 callback 時是同步還是異步的?

到此這篇關于JavaScript中回調的文章就介紹到這了,更多相關JavaScript的回調內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!

原文鏈接:https://mp.weixin.qq.com/s/zqDy3ZjIKTK-9Mg7FjWLnA

延伸 · 閱讀

精彩推薦
  • js教程ES5和ES6中類的區別總結

    ES5和ES6中類的區別總結

    這篇文章主要給大家介紹了ES5和ES6中類的區別的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋...

    Totora612112021-12-16
  • js教程JavaScript實現通訊錄功能

    JavaScript實現通訊錄功能

    這篇文章主要為大家詳細介紹了JavaScript實現通訊錄功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    書寫夢想的鉛筆頭5602021-12-20
  • js教程js定時器出現第一次延遲的原因及解決方法

    js定時器出現第一次延遲的原因及解決方法

    在本篇文章里小編給大家整理的是一篇關于js定時器出現第一次延遲的原因及解決方法,對此有需要的朋友們可以學習下。...

    宋宋大人4892021-12-24
  • js教程微信小程序學習之自定義滾動彈窗

    微信小程序學習之自定義滾動彈窗

    這篇文章主要給大家介紹了關于微信小程序學習之自定義滾動彈窗的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考...

    юноша9042021-12-15
  • js教程微信小程序實現登錄注冊功能

    微信小程序實現登錄注冊功能

    這篇文章主要介紹了微信小程序實現登錄注冊功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    保護我方豆豆5112021-12-22
  • js教程js正則表達式簡單校驗方法

    js正則表達式簡單校驗方法

    在本篇文章里小編給大家整理了一篇關于js正則表達式簡單校驗方法,有需要的朋友們可以參考下。...

    小妮淺淺11152021-12-24
  • js教程javascript實現隨機抽獎功能

    javascript實現隨機抽獎功能

    這篇文章主要為大家詳細介紹了javascript實現隨機抽獎功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    彴兗6922021-12-23
  • js教程javascript的事件描述

    javascript的事件描述

    本文主要為大家介紹javascript事件的基礎知識,有需要的朋友可以參考下...

    js教程網9362021-12-15
主站蜘蛛池模板: 狠狠干五月天 | 日韩电影在线 | 亚洲色视频| 91精品久久| 久久国产综合 | 国产最新一区 | 日韩免费高清视频 | 国产一区| 国产精品国产三级国产aⅴ中文 | 99久久毛片免费观看 | 一区二区免费看 | 成人a视频片观看免费 | 99久久精品一区二区成人 | 亚洲成人午夜电影 | 国产色 | 黄色一级在线观看 | 久久精品日产第一区二区三区 | www久久九| 一区二区三区不卡视频 | 久久久久久亚洲精品 | 精品视频 | 亚洲免费成人在线视频 | 无毛av | 国产午夜精品一区二区三区免费 | 日韩欧美三级 | 亚洲精品影院 | 欧美日韩精品在线观看 | 国产成人一区二区三区 | 精品一区二区三区成人精品 | 成年人综合网 | 国产综合精品一区二区三区 | 91在线视频观看 | 久久精品一区二区三区不卡牛牛 | 亚洲成人一区二区在线观看 | 国产精品美女久久久久久久久久久 | 国产麻豆一区二区三区 | 国产精品久久久久久久久久 | 国产精品久久久久久久久久久久久久 | 蜜臀精品久久久久久蜜臀 | 久久久91 | 国产精品一级 |