作者:Shadeed
译者:前端小智
来源:dmitripavlutin

点赞再看,微信搜索**【大迁世界】,B站关注【前端小智】**这个没有大厂背景,但有着一股向上积极心态人。本文 GitHub https://github.com/qq449245884/xiaozhi 上已经收录,文章的已分类,也整理了很多我的文档,和教程资料。

最近开源了一个 Vue 组件,还不够完善,欢迎大家来一起完善它,也希望大家能给个 star 支持一下,谢谢各位了。

github 地址:https://github.com/qq449245884/vue-okr-tree

回调函数是每个 JS 开发人员都应该知道的概念之一。 回调用于数组,计时器函数,promise,事件处理程序等中。

在本文中,会解释回调函数的概念。 另外,还会帮助智米们区分两种回调:同步和异步

1.回调函数

我们编写一个问候的函数,首先创建一个函数greet(name),该函数返回欢迎消息:

function greet(name) {return `Hello, ${name}!`;
}greet('小智'); // => 'Hello, 小智!'

如果要向一些人问候怎么做?这里,我们可以使用 array.map() 方法:

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

persons.map(greet)接受person数组的每一项,并使用每一项作为调用参数来调用函数greet()greet('小智')greet('王大冶')

有趣的是persons.map(greet)方法接受greet()函数作为参数。 这样做会使reet()成为回调函数。

persons.map(greet)是一个接受另一个函数作为参数的函数,因此将其命名为高阶函数

高阶函数承担调用回调函数的全部责任,并为其提供正确的参数。

在前面的示例中,高阶函数persons.map(greet)负责调用greet()回调函数,并将数组的每个项目作为参数:'小智''王大冶'

我们可以可以自己编写使用回调的高阶函数。例如,这里有一个等价的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 = ['小智', '王大冶']const messages = map(persons, greet);messages // ["Hello, 小智!", "Hello, 王大冶!"]

map(array, callback)是一个高阶函数,因为它接受回调函数作为参数,然后在它的函数体内部调用回调函数:callback(item)

2.同步回调

回调的调用方式有两种:同步和异步回调。

同步回调是在使用回调的高阶函数执行期间执行的。

换句话说,同步回调处于阻塞状态:高阶函数要等到回调完成执行后才能完成其执行。

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()是一个同步回调函数,因为它与高阶函数map()同时执行。

2.1 同步回调的例子

很多原生 JavaScript 类型的方法都使用同步回调。

最常用的是数组方法,例如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.异步回调

异步回调在执行高阶函数之后执行。

简而言之,异步回调是非阻塞的:高阶函数无需等待回调即可完成其执行,高阶函数可确保稍后在特定事件上执行回调。

在下面的示例中,later()函数的执行延迟为2秒

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

3.1 异步回调的示例

计时器函数的异步回调:

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

DOM 事件监听器也是异步调用事件处理函数(回调函数的一种子类型)

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

4. 异步回调函数 vs 异步函数

放在函数定义之前的特殊关键字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()

async函数是 Promise 的语法糖。 当遇到表达式await <promise>时(注意,调用fetch()将返回一个 promise),异步函数将暂停执行直到该promise得以解决。

异步回调函数和异步函数是不同的术语。

异步回调函数由高阶函数以非阻塞方式执行。 但是异步函数在等待promise(await <promise>)解析时暂停其执行。

但是,我们可以将异步函数用作异步回调!

我们异步函数fetchUserNames()设为单击按钮时调用的异步回调:

const button = document.getElementById('fetchUsersButton');button.addEventListener('click', fetchUserNames);

总结

回调是一个可以作为参数接受并由另一个函数(高阶函数)执行的函数.

有两种回调函数:同步和异步。

同步回调函数与使用回调函数的高阶函数同时执行,同步回调是阻塞的。另一方面,异步回调的执行时间比高阶函数的执行时间晚,异步回调是非阻塞的。

完~,感谢大家的观看,我是小智,我去刷碗啦!


代码部署后可能存在的BUG没法实时知道,事后为了解决这些BUG,花了大量的时间进行log 调试,这边顺便给大家推荐一个好用的BUG监控工具 Fundebug。

原文:https://dmitripavlutin.com/javascript-variables-practices/

交流

文章每周持续更新,可以微信搜索「 大迁世界 」第一时间阅读和催更(比博客早一到两篇哟),本文 GitHub https://github.com/qq449245884/xiaozhi 已经收录,整理了很多我的文档,欢迎Star和完善,大家面试可以参照考点复习,另外关注公众号,后台回复福利,即可看到福利,你懂的。

有关JavaScript中回调函数的所有内容!相关推荐

  1. 彻底理解JavaScript中回调函数 (推荐)

    在javascript中回调函数非常重要,它们几乎无处不在.像其他更加传统的编程语言都有回调函数概念,但是非常奇怪的是,完完整整谈论回调函数的在线教程比较少,倒是有一堆关于call()和apply() ...

  2. javascript中回调函数的理解和应用

    一. 什么是回调函数? 被作为实参传入另一函数,并在该外部函数内被调用,用以来完成某些任务的函数,称为回调函数. function f1(fn) {let a =1;console.log(a,'a' ...

  3. 如何用JavaScript的回调函数做出承诺

    by Adham El Banhawy 由Adham El Banhawy 如何用JavaScript的回调函数做出承诺 (How to make a Promise out of a Callbac ...

  4. JavaScript:回调函数(callback)

    前言 callback,大家都知道是回调函数的意思.如果让你举些callback的例子,我相信你可以举出一堆.但callback的概念你知道吗?你自己在实际应用中能不能合理利用回调实现功能? 我们在平 ...

  5. Javascript中的函数重载-最佳做法

    用JavaScript伪造函数重载的最佳方法是什么? 我知道不可能像其他语言一样重载Javascript中的函数. 如果我需要两个函数一起使用foo(x)和foo(x,y,z) ,这是最佳/首选方式: ...

  6. JavaScript中的函数表达式

    在JavaScript中,函数是个非常重要的对象,函数通常有三种表现形式:函数声明,函数表达式和函数构造器创建的函数. 本文中主要看看函数表达式及其相关的知识点. 函数表达式 首先,看看函数表达式的表 ...

  7. 浅析 JavaScript 中的 函数 uncurrying 反柯里化

    柯里化 柯里化又称部分求值,其含义是给函数分步传递参数,每次传递参数后部分应用参数,并返回一个更具体的函数接受剩下的参数,这中间可嵌套多层这样的接受部分参数函数,直至返回最后结果. 因此柯里化的过程是 ...

  8. JavaScript中Exists函数

    JavaScript中Exists函数是如果 Dictionary 对象中存在所指定的主键则返回 true,否则返回 false.使用方法: object.Exists(key) 其中object是必 ...

  9. javascript中setTimeout()函数

    javascript中setTimeout()函数 大家都知道javascript中的setTimeput()函数的作用,一般会用他来处理一些连续的事情,们先看一个例子: <head>   ...

最新文章

  1. 企业 - php nginx memcache
  2. c++ getline 读不到东西_C++ getline()函数问题
  3. Solidity 官方文档中文版 2_Ethereum 智能合约介绍
  4. binder-swagger-java v0.5.0,Swagger API 框架
  5. 大数据分析必须要会的数据处理技巧!!!
  6. oracle 对象定义被修改,oracle 数据对象_xspaces
  7. Netty集成WebSocket实现客户端、服务端长连接
  8. 京冀津城际铁路网规划大全
  9. 我国开始研制电子计算机,我国从( )年开始研制电子计算机。
  10. 《区块链技术原理》笔记
  11. ⼤数据平台基础架构及解决⽅案
  12. 模拟信号拉线位移编码器是如何来校准的?
  13. 不同类型的云计算专业知识,推荐几本专业云计算技术书籍
  14. python怎么爬取电影海报_Python 爬取猫眼数据分析《无名之辈》为何能逆袭成黑马?...
  15. MAC Book 配置java环境详细
  16. Apache Flink从入门到放弃——Flink简介(一)
  17. 什么是wind量化平台接口?
  18. [5GC] [图解5GC信令流程] PDU会话建立
  19. android AVB2.0(一)工作原理及编译配置
  20. 地震发生时的避险与逃生

热门文章

  1. 海绵宝宝python代码_python的初体验
  2. 求一元二次方程的根 java
  3. slim.fully_connected()
  4. 如何批量生成食品电子监管码
  5. Flutter-分段滑块
  6. 干什么挣钱快,2个冷门项目让你迅速发家致富
  7. mysql查询跟某个人同在部门_MySQL 查询习题详解
  8. Ubuntu17.04+Nvidia GT 640LE+CUDA9.0+cuDNN7.05+Tensorflow1.5r0(GPU)+Anaconda5.01(python3.6)安装
  9. [2021东软杯_WEB]easyinject (LDAP盲注爆破)
  10. 如何利用BI搭建电商数据分析平台 1