回调是每个JS开发人员都应该知道的概念之一。回调用于数组、定时器函数、承诺、事件处理程序等。本文解释了回调函数的概念。此外,它将帮助Smartmis区分两种回调:同步和异步。1.回调函数我们写一个问候函数,首先创建一个函数greet(name),返回一条欢迎信息:functiongreet(name){return`Hello,${name}!`;}greet('小智');//=>'你好,小智!'如果你想跟某些人打招呼怎么办?这里,我们可以使用array.map()方法:constpersons=['小智','王大叶']constmessages=persons.map(greet)messages//["你好,小智!","你好,王大叶!"]persons.map(greet)接受person数组的每一项,并将每一项作为调用参数调用函数greet():greet('小智'),greet('王大爷')。有趣的是persons.map(greet)方法接受greet()函数作为参数。这样做会使reet()成为回调函数。persons.map(greet)是一个将另一个函数作为参数的函数,因此得名高阶函数。高阶函数全权负责调用回调函数并为其提供正确的参数。在前面的例子中,高阶函数persons.map(greet)负责调用greet()回调函数,将数组的每一项作为参数:'Xiaozhi'和'WangDaye'。我们可以编写自己的使用回调的高阶函数。例如,这里是等效的array.map()方法`你好,${name}!`;}constpersons=['小智','王大业']constmessages=map(persons,greet);messages//["你好,小智!","你好,王大业!"]map(array,callback)是一个高阶函数,因为它接受一个回调函数作为参数,然后在它的函数体内调用回调函数:callback(item)。2.同步回调回调的调用方式有两种:同步回调和异步回调。同步回调是在使用回调的高阶函数执行期间执行的。换句话说,同步回调是阻塞的:在回调完成执行之前,高阶函数无法完成其执行。functionmap(array,callback){console.log('map()started');constmappedArray=[];for(constitemofarray){mappedArray.push(callback(item))}console.log('map()completed');returnmappedArray;}functiongreet(name){console.log('greet()被调用');return`Hello,${name}!`;}constpersons=['小智'];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=人。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.异步回调异步回调在高阶函数执行后执行。简而言之,异步回调是非阻塞的:高阶函数不需要等待回调完成它们的执行,高阶函数确保回调稍后在特定事件上执行。在下面的示例中,later()函数的执行延迟了2秒console.log('setTimeout()started')setTimeout(functionlater(){console.log('later()wascalled')},2000)console.log('setTimeout()completed')//setTimeout()开始//setTimeout()完成//later()被调用(2秒后)3.1异步回调示例定时器函数的异步回调:setTimeout(functionlater(){console.log('2秒过去了!');},2000);setInterval(functionrepeat(){console.log('每2秒');},2000);DOM事件监听器也是异步调用事件处理函数(回调函数的一个子类));})//当按钮被点击时,它会打印'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时(注意调用fetch()将返回一个promise),async函数将暂停执行直到promise被解析。异步回调函数和异步函数是不同的术语。异步回调函数由高阶函数以非阻塞方式执行。但是异步函数在等待promise(await)解决时暂停执行。但是,我们可以使用异步函数作为异步回调!我们的异步函数fetchUserNames()设置为单击按钮时调用的异步回调:constbutton=document.getElementById('fetchUsersButton');button.addEventListener('click',fetchUserNames);Summary可以作为参数接受并由另一个函数(高阶函数)执行。回调函数有两种:同步和异步。同步回调函数与使用回调函数的高阶函数并发执行,同步回调是阻塞的。另一方面,异步回调比高阶函数晚执行,异步回调是非阻塞的。完~,谢谢观看,我是小智,我去洗碗了!作者:Shadeed译者:前端小智来源:dmitripavlutin原文:https://dmitripavlutin.com/javascript-variables-practices/微信公众号“大千世界”,可通过以下二维码关注。转载本文请联系大千世界公众号。
