作者:Shadeed译者:前端小智来源:dmitripavlutin有梦想,有干货,微信搜索【大千世界】关注这位凌晨还在洗碗的洗碗智慧。本文已收录到GitHubhttps://github.com/qq449245884/xiaozhi,里面有完整的测试站点、资料和我的一线厂商访谈系列文章。回调是每个JS开发人员都应该知道的概念之一。回调用于数组、定时器函数、承诺、事件处理程序等。本文解释了回调函数的概念。此外,它将帮助Smartmis区分两种回调:同步和异步。1.回调函数我们写一个问候函数,首先创建一个函数greet(name),它返回一条欢迎信息:functiongreet(name){return`Hello,${name}!`;}greet('Xiaozhi');//=>'你好,阿什!'如果你想和一些人打招呼怎么办?这里,我们可以使用array.map()方法:constpersons=['小智','王大爷']constmessages=persons.map(greet)messages//["你好,小智!","你好,王Daye!"]persons.map(greet)接受person数组的每一项,并将每一项作为调用参数调用函数greet():greet('小智'),greet('王大爷')。有趣的是persons.map(greet)方法接受greet()函数作为参数。这样做会使reet()成为回调函数。persons.map(greet)是一个将另一个函数作为参数的函数,因此得名高阶函数。高阶函数全权负责调用回调函数并为其提供正确的参数。在前面的例子中,高阶函数persons.map(greet)负责调用greet()回调函数,将数组的每一项作为参数:'Xiaozhi'和'WangDaye'。我们可以编写自己的使用回调的高阶函数。例如,这是一个等效的array.map()方法functionmap(array,callback){constmappedArray=[];for(constitemofarray){mappedArray.push(callback(item));}返回映射数组;}functiongreet(name){return`Hello,${name}!`;}constpersons=['小智','王大爷']constmessages=map(persons,greet);messages//["你好,小智!","你好,王大爷!"]map(array,callback)是一个高阶函数,因为它接受一个回调函数作为参数,然后在它的函数体内部调用回调函数:callback(item)。2.同步回调回调的调用方式有两种:同步回调和异步回调。同步回调是在使用回调的高阶函数执行期间执行的。换句话说,同步回调是阻塞的:在回调完成执行之前,高阶函数无法完成其执行。functionmap(array,callback){console.log('map()start');constmappedArray=[];for(constitemofarray){mappedArray.push(callback(item))}console.log('map()done');returnmappedArray;}functiongreet(name){console.log('greet()wascalled');return`Hello,${name}!`;}constpersons=['Xiaozhi'];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)://on数组同步回调示例constpersons=['小智','前端小智']persons.forEach(functioncallback(name){console.log(name);});//小智//前端小智constnameStartingA=persons.find(functioncallback(name){returnname[0].toLowerCase()==='Small';})//nameStartingA//小智constcountStartingA=persons.reduce(functioncallback(count,name){conststartsA=name[0].toLowerCase()==='small';returnstartsA?count+1:count;},0);countStartingA//13.异步回调异步回调在higher-之后执行订单功能被执行。简而言之,异步回调是非阻塞的:高阶函数不需要等待回调完成它们的执行,高阶函数确保回调稍后在特定事件上执行。在下面的示例中,later()函数的执行延迟了2秒console.log('setTimeout()started')setTimeout(functionlater(){console.log('later()wascalled')},2000)console.log('setTimeout()finished')//setTimeout()开始//setTimeout()完成//later()被调用(2秒后)3.1异步回调示例定时器函数的异步回调:setTimeout(functionlater(){console.log('2秒过去了!');},2000);setInterval(functionrepeat(){console.log('每2秒');},2000);DOM事件监听器也是异步调用事件处理函数(回调函数的子类型)clicked!');})//当按钮被点击时,它会打印'Iwasclicked!'4.异步回调函数vs异步函数放在函数定义前的特殊关键字async创建异步函数:asyncfunctionfetchUserNames(){constresp=awaitfetch('https://api.github.com/users?per_page=5');constusers=awaitresp.json();constnames=users.map(({login})=>login);console.log(names);}fetchUserNames()是异步的,因为它有async前缀。函数awaitfetch('https://api.github.com/users?per_page=5')来自GitHub的前5个用户。然后从响应对象中提取JSON数据:awaitresp.json()。异步函数是Promises的语法糖。当遇到表达式await
