5
Author: Shadeed
Translator: Frontend Xiaozhi
Source: dmitripavlutin
There are dreams, dry goods, WeChat search [Da Qian World] Pay attention to this Shuawanzhi who is still doing dishes in the early morning.
This article GitHub https://github.com/qq449245884/xiaozhi has been included, the first-line interview complete test site, information and my series of articles.

Callback function is one of the concepts that every JS developer should know. Callbacks are used in arrays, timer functions, promises, event handlers, etc.

In this article, the concept of callback functions will be explained. In addition, it will also help distinguish between two callbacks: 161c2e33a5a0ea synchronous and asynchronous .

1. Callback function

We write a greeting function. First, create a function greet(name) , which returns a welcome message:

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

greet('小智'); // => 'Hello, 小智!'

What if you want to greet some people? Here, we can use the array.map() method:

const persons = ['小智', '王大冶']
const messages = persons.map(greet)

messages // ["Hello, 小智!", "Hello, 王大冶!"]

persons.map(greet) accepts person array, and uses each item as a call parameter to call the function greet() : greet('Xiaozhi'), greet('Wang Daye').

The interesting thing is that the persons.map(greet) method accepts the greet() function as a parameter. Doing so will make reet() a callback function.

persons.map(greet) is a function that accepts another function as a parameter, so it is named higher-order function .

Higher-order functions take full responsibility for calling the callback function and provide it with the correct parameters.

In the previous example, the higher-order function persons.map(greet) is responsible for calling the greet() , taking each item of the array as a parameter: ' and Daye'.

We can write our own higher-order functions that use callbacks. For example, here is an array.map() method

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 = ['小智', '王大冶']

const messages = map(persons, greet);

messages // ["Hello, 小智!", "Hello, 王大冶!"]

map(array, callback) is a higher-order function, because it accepts a callback function as a parameter, and then calls the callback function within its function body: callback(item) .

2. Synchronous callback

There are two ways to call callbacks: synchronous and asynchronous callbacks.

Synchronous callbacks are executed during the execution of higher-order functions that use callbacks.

In other words, synchronous callbacks are in a blocking state: higher-order functions cannot complete their execution until the callback has completed execution.

function map(array, callback) {
  console.log('map() 开始');
  const mappedArray = [];
  for (const item of array) { mappedArray.push(callback(item)) }
  console.log('map() 完成');
  return mappedArray;
}

function greet(name) {
  console.log('greet() 被调用 ');
  return `Hello, ${name}!`;
}
const persons = ['小智'];

map(persons, greet);

// map() 开始
// greet() 被调用 
// map() 完成

greet() is a synchronous callback function because it is map() simultaneously with the higher-order function 061c2e33a5a2f2.

2.1 Examples of synchronous callbacks

Many native JavaScript-type methods use synchronous callbacks.

The most commonly used is the array method, such as array.map(callback) , array.forEach(callback) , array.find(callback) , array.filter(callback) , array.reduce(callback, init) :

// 数组上的同步回调的示例

const persons = ['小智', '前端小智']
persons.forEach(
  function callback(name) {
    console.log(name);
  }
);
// 小智
// 前端小智

const nameStartingA = persons.find(
  function callback(name) {
    return name[0].toLowerCase() === '小';
  }
)
// nameStartingA // 小智

const countStartingA = persons.reduce(
  function callback(count, name) {
    const startsA = name[0].toLowerCase() === '小';
    return startsA ? count + 1 : count;
  }, 
  0
);

countStartingA // 1

3. Asynchronous callback

Asynchronous callbacks are executed after the execution of higher-order functions.

In short, asynchronous callbacks are non-blocking: higher-order functions do not need to wait for the callback to complete their execution, and higher-order functions can ensure that callbacks are executed later on specific events.

In the example below, the execution delay of the later()

console.log('setTimeout() 开始')
setTimeout(function later() {
  console.log('later() 被调用')
}, 2000)
console.log('setTimeout() 完成')

// setTimeout() 开始
// setTimeout() 完成
// later() 被调用(2秒后)

3.1 Examples of asynchronous callbacks

Asynchronous callback of timer function:

setTimeout(function later() {
  console.log('2秒过去了!');
}, 2000);

setInterval(function repeat() {
  console.log('每2秒');
}, 2000);

The DOM event listener is also an asynchronous call to the event processing function (a subtype of the callback function)

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

myButton.addEventListener('click', function handler() {
  console.log('我被点击啦!');
})
// 点击按钮时,才会打印'我被点击啦!'

4. Asynchronous callback function vs asynchronous function

async placed before the function definition creates an asynchronous function:

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() is asynchronous because its prefix is async . The function await fetch('https://api.github.com/users?per_page=5') from the top 5 users on GitHub. Then extract the JSON data from the response object: await resp.json() .

async function is syntactic sugar Promise When the expression await <promise> is encountered (note that calling fetch() will return a promise), the asynchronous function will suspend execution until the promise is resolved.

Asynchronous callback function and asynchronous function are different terms.

Asynchronous callback functions are executed by higher-order functions in a non-blocking manner. But the asynchronous function suspends its execution while waiting for the promise ( await <promise> ) to resolve.

However, we can use asynchronous functions as asynchronous callbacks!

Our asynchronous function fetchUserNames() set as an asynchronous callback called when the button is clicked:

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

button.addEventListener('click', fetchUserNames);

Summarize

A callback is a function that can be accepted as a parameter and executed by another function (a higher-order function).

There are two kinds of callback functions: synchronous and asynchronous.

The synchronous callback function is executed at the same time as the higher-order function that uses the callback function, and the synchronous callback is blocked. On the other hand, the execution time of asynchronous callbacks is later than the execution time of higher-order functions, and asynchronous callbacks are non-blocking.

End~, thank you all for watching, I’m Xiaozhi, I’m going to do the dishes!


code is deployed, the possible bugs cannot be known in real time. In order to solve these bugs afterwards, a lot of time was spent on log debugging. By the way, I would like to recommend a useful BUG monitoring tool Fundebug .

Original: https://dmitripavlutin.com/javascript-variables-practices/

comminicate

If you have dreams and dry goods, search for [Daily Move to the World] attention to this wise brush who is still doing dishes in the early morning.

This article GitHub https://github.com/qq449245884/xiaozhi has been included, the first-line interview complete test sites, materials and my series of articles.


王大冶
68k 声望104.9k 粉丝