欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

一篇文章看懂JavaScript中的回調(diào)

 更新時(shí)間:2021年01月05日 15:12:18   作者:瘋狂的技術(shù)宅  
這篇文章主要給大家介紹了如何通過(guò)一篇文章看懂JavaScript中的回調(diào),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

前言

回調(diào)函數(shù)是每個(gè)前端程序員都應(yīng)該知道的概念之一?;卣{(diào)可用于數(shù)組、計(jì)時(shí)器函數(shù)、promise、事件處理中。

本文將會(huì)解釋回調(diào)函數(shù)的概念,同時(shí)幫你區(qū)分兩種回調(diào):同步和異步。

回調(diào)函數(shù)

首先寫一個(gè)向人打招呼的函數(shù)。

只需要?jiǎng)?chuàng)建一個(gè)接受 name 參數(shù)的函數(shù) greet(name)。這個(gè)函數(shù)應(yīng)返回打招呼的消息:

function greet(name) {
 return `Hello, ${name}!`;
}

greet('Cristina'); // => 'Hello, Cristina!'

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

const persons = ['Cristina', 'Ana'];

const messages = persons.map(greet);
messages; // => ['Hello, Cristina!', 'Hello, Ana!'] 

persons.map(greet) 獲取 persons 數(shù)組的所有元素,并分別用每個(gè)元素作為調(diào)用參數(shù)來(lái)調(diào)用 greet() 函數(shù):greet('Cristina'), greet('Ana')。

有意思的是 persons.map(greet) 方法可以接受 greet()  函數(shù)作為參數(shù)。這樣 greet()  就成了回調(diào)函數(shù)。

persons.map(greet) 是用另一個(gè)函數(shù)作為參數(shù)的函數(shù),因此被稱為高階函數(shù)。

回調(diào)函數(shù)作為高階函數(shù)的參數(shù),高階函數(shù)通過(guò)調(diào)用回調(diào)函數(shù)來(lái)執(zhí)行操作。

重要的是高階函數(shù)負(fù)責(zé)調(diào)用回調(diào),并為其提供正確的參數(shù)。

在前面的例子中,高階函數(shù) persons.map(greet) 負(fù)責(zé)調(diào)用  greet()  函數(shù),并分別把數(shù)組中所有的元素 'Cristina' 和 Ana ' 作為參數(shù)。

這就為識(shí)別回調(diào)提供了一條簡(jiǎn)單的規(guī)則。如果你定義了一個(gè)函數(shù),并將其作參數(shù)提供給另一個(gè)函數(shù)的話,那么這就創(chuàng)建了一個(gè)回調(diào)。

你可以自己編寫使用回調(diào)的高階函數(shù)。下面是 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) 是一個(gè)高階函數(shù),因?yàn)樗没卣{(diào)函數(shù)作為參數(shù),然后在其主體內(nèi)部調(diào)用該回調(diào)函數(shù):callback(item)。

注意,常規(guī)函數(shù)(用關(guān)鍵字 function 定義)或箭頭函數(shù)(用粗箭頭 => 定義)同樣可以作為回調(diào)使用。

同步回調(diào)

回調(diào)的調(diào)用方式有兩種:同步和異步回調(diào)。

同步回調(diào)是“阻塞”的:高階函數(shù)直到回調(diào)函數(shù)完成后才繼續(xù)執(zhí)行。

例如,調(diào)用 map() 和 greet() 函數(shù)。

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()  是同步回調(diào)。

同步回調(diào)的步驟:

  1. 高階函數(shù)開(kāi)始執(zhí)行:'map() starts'
  2. 回調(diào)函數(shù)執(zhí)行:'greet() called'
  3. .最后高階函數(shù)完成它自己的執(zhí)行過(guò)程:'map() completed'

同步回調(diào)的例子

許多原生 JavaScript 類型的方法都使用同步回調(diào)。

最常用的是 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)  方法也能接受同步執(zhí)行的回調(diào):

// 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'

異步回調(diào)

異步回調(diào)是“非阻塞的”:高階函數(shù)無(wú)需等待回調(diào)完成即可完成其執(zhí)行。高階函數(shù)可確保稍后在特定事件上執(zhí)行回調(diào)。

在以下的例子中,later() 函數(shù)的執(zhí)行延遲了 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() 是一個(gè)異步回調(diào),因?yàn)?setTimeout(later,2000) 啟動(dòng)并完成了執(zhí)行,但是 later() 在 2 秒后執(zhí)行。

異步調(diào)用回調(diào)的步驟:

  1. 高階函數(shù)開(kāi)始執(zhí)行:'setTimeout()starts'
  2. 高階函數(shù)完成其執(zhí)行:'setTimeout() completed'
  3. 回調(diào)函數(shù)在 2 秒鐘后執(zhí)行:'later() called'

異步回調(diào)的例子

計(jì)時(shí)器函數(shù)異步調(diào)用回調(diào):

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 事件偵聽(tīng)器還異步調(diào)用事件處理函數(shù)(回調(diào)函數(shù)的子類型):

const myButton = document.getElementById('myButton');

myButton.addEventListener('click', function handler() {
 console.log('Button clicked!');
});
// Logs 'Button clicked!' when the button is clicked

4.異步回調(diào)函數(shù)與異步函數(shù)

在函數(shù)定義之前加上特殊關(guān)鍵字 async 會(huì)創(chuàng)建一個(gè)異步函數(shù):

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() 是異步的,因?yàn)樗?async 為前綴。函數(shù)  await fetch('https://api.github.com/users?per_page=5') 從 GitHub 上獲取前5個(gè)用戶 。然后從響應(yīng)對(duì)象中提取 JSON 數(shù)據(jù):await resp.json()。

異步函數(shù)是 promise 之上的語(yǔ)法糖。當(dāng)遇到表達(dá)式 await <promise>  (調(diào)用  fetch()  會(huì)返回一個(gè)promise)時(shí),異步函數(shù)會(huì)暫停執(zhí)行,直到 promise 被解決。

異步回調(diào)函數(shù)和異步函數(shù)是不同的兩個(gè)術(shù)語(yǔ)。

異步回調(diào)函數(shù)由高階函數(shù)以非阻塞方式執(zhí)行。但是異步函數(shù)在等待 promise(await <promise>)解析時(shí)會(huì)暫停執(zhí)行。

但是你可以把異步函數(shù)用作異步回調(diào)!

讓我們把異步函數(shù) fetch UserNames() 設(shè)為異步回調(diào),只需單擊按鈕即可調(diào)用:

const button = document.getElementById('fetchUsersButton');

button.addEventListener('click', fetchUserNames);

總結(jié)

回調(diào)是一個(gè)可以作為參數(shù)傳給另一個(gè)函數(shù)(高階函數(shù))執(zhí)行的函數(shù)。

回調(diào)函數(shù)有兩種:同步和異步。

同步回調(diào)是阻塞的。

異步回調(diào)是非阻塞的。

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

到此這篇關(guān)于JavaScript中回調(diào)的文章就介紹到這了,更多相關(guān)JavaScript的回調(diào)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • JavaScript頁(yè)面回流與重繪

    JavaScript頁(yè)面回流與重繪

    這篇文章主要介紹了JavaScript頁(yè)面回流與重繪,一個(gè)html頁(yè)面是一個(gè)整體,當(dāng)這個(gè)整體中的某一個(gè)部分發(fā)生改變,那么這個(gè)頁(yè)面整體會(huì)重新進(jìn)行渲染,而如果我們采用添加標(biāo)簽的方式,每次添加一個(gè)標(biāo)簽,就會(huì)讓每一次頁(yè)面都重新渲染,性能急劇下降,下面來(lái)看看具體內(nèi)容吧
    2022-01-01
  • TypeScript?類型斷言的幾種實(shí)現(xiàn)

    TypeScript?類型斷言的幾種實(shí)現(xiàn)

    本文主要介紹了TypeScript?類型斷言的實(shí)現(xiàn),有使用關(guān)鍵字as和標(biāo)簽<>兩種方式,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-01-01
  • js讀寫(刪除)Cookie實(shí)例詳解

    js讀寫(刪除)Cookie實(shí)例詳解

    js操作Cookie包括:寫cookies、讀取cookies、刪除cookies以及使用示例,感興趣的朋友可以參考下哈
    2013-04-04
  • JS中parseInt()和map()用法分析

    JS中parseInt()和map()用法分析

    這篇文章主要介紹了JS中parseInt()和map()用法,結(jié)合實(shí)例形式分析了parseInt()和map()方法的功能、參數(shù)、具體用法與相關(guān)注意事項(xiàng),需要的朋友可以參考下
    2016-12-12
  • mpvue實(shí)現(xiàn)微信小程序快遞單號(hào)查詢代碼

    mpvue實(shí)現(xiàn)微信小程序快遞單號(hào)查詢代碼

    這篇文章主要介紹了mpvue實(shí)現(xiàn)微信小程序快遞單號(hào)查詢,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-04-04
  • JavaScript中訪問(wèn)id對(duì)象 屬性的方式訪問(wèn)屬性(實(shí)例代碼)

    JavaScript中訪問(wèn)id對(duì)象 屬性的方式訪問(wèn)屬性(實(shí)例代碼)

    下面小編就為大家?guī)?lái)一篇JavaScript中訪問(wèn)id對(duì)象 屬性的方式訪問(wèn)屬性(實(shí)例代碼)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-10-10
  • js實(shí)現(xiàn)在文本框光標(biāo)處添加字符的方法介紹

    js實(shí)現(xiàn)在文本框光標(biāo)處添加字符的方法介紹

    在開(kāi)發(fā)應(yīng)用中,經(jīng)常會(huì)遇到一些技術(shù)上的問(wèn)題,比如:怎樣讓js在文本框光標(biāo)處添加字符,本文將以此問(wèn)題進(jìn)行詳細(xì)介紹,需要了解的朋友可以參考下
    2012-11-11
  • TypeScript類型斷言VS類型守衛(wèi)示例詳解

    TypeScript類型斷言VS類型守衛(wèi)示例詳解

    這篇文章主要為大家介紹了TypeScript類型斷言VS類型守衛(wèi)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • 數(shù)據(jù)排序誰(shuí)最快(javascript中的Array.prototype.sort PK 快速排序)

    數(shù)據(jù)排序誰(shuí)最快(javascript中的Array.prototype.sort PK 快速排序)

    今天在51js論壇中看到一個(gè)網(wǎng)友發(fā)布了一個(gè)javasctipt實(shí)現(xiàn)的快速排序的算法,前些日子工作中也涉及到j(luò)avasctipt中數(shù)據(jù)排序的應(yīng)用,當(dāng)時(shí)為了提高排序速度,使用的也是快速排序的算法。
    2007-01-01
  • JavaScript中DOM操作常用事件總結(jié)

    JavaScript中DOM操作常用事件總結(jié)

    這篇文章主要為大家詳細(xì)介紹了JavaScript中常用的幾個(gè)DOM事件,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2022-04-04

最新評(píng)論