js中回调函数(callback)的一些理解

前言

我个人在学习Node.js相关知识时遇到了回调函数这个概念,虽然之前已经在c,c++等编程语言中用到过它,但还一直未对其机制有深入了解,这次就来好好谈一下它。

 

概念理解

百度对它的解释是回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。

Google里的解释是A callback is a function that is passed as an argument to another function and is executed after its parent function has completed.

字面上的理解,回调函数就是一个参数,将这个函数作为参数传到另一个函数里面,当那个函数执行完之后,再执行传进去的这个函数。这个过程就叫做回调。

这里我想把它通俗化来讲,小时候大家应该都有自己喜欢看的动画片,但是平时上学期间我们都会被家长“严格管制”。下午放学回家后,爸妈会让自己先写完作业才能看电视里放的动画片。

其实这就是一个回调的过程。你建了个函数b(看动画片),但前提是要写完作业,写作业的过程相当于执行函数a。在现实生活中你要写完作业才能看动画片,即在执行过程中需要等函数a执行完之后才能执行函数b。

不过必须清楚一点:函数b是以参数形式传给函数a的,b是回调函数。

 

简单的例子

function a(callback){
   alert("这是first函数a");
   var x =1;
   var y=2;
  return callback(x,y);
 }
 function b(x,y){
   alert("这是回调函数b");
   return x+y;
 }
 $(function(){
   var result = a(b);
   alert("result = "+ result);
 });

输出结果为:

这是first函数a

这是回调函数b

result = 3

这里函数首先执行了first函数a,之后调用了回调函数b,最后返回函数a的返回值。

 

回调函数的种类(按功能划分)

1.同步回调

它是一种阻塞式回调,比方说一段代码逻辑没有执行完毕,代码会一直等待,而不会去执行下一段代码逻辑。

2.异步回调

它是一种非阻塞式回调,比方说一段代码逻辑没有执行完毕,代码执行可以不卡在这块不动,而是可以去执行下一段代码逻辑。

二者根本区别

在同步回调里,回调函数的调用一定发生在主函数返回之前。

在异步回调里,回调函数的调用有可能是在起始函数返回之后。

 

应用场景

回调函数应用场景多用在使用 js 写组件时,尤其是组件的事件很多都需要回调函数的支持。

 

个人实例分享

前端登录界面发送请求,后台Node.js连接数据库实现登录功能

html部分代码:

<form action="#" id="form" name="form" method="post">
<div class="input_outer">
<span class="u_user"></span>
<input id="acnt" name="acnt" class="text" style="color:#FFFFFF !important;" type="text"
placeholder="请输入账号">
</div>
<div class="input_outer">
<span class="us_uer"></span>
<input id="pswd" name="pswd" class="text"
style="color:#FFFFFF !important;position: absolute; z-index: 100;"
type="password" placeholder="请输入密码">
</div>
<div class="mb2">
<a class="act-but submit" style="color: #FFFFFF">登录</a>
</div>
</form>

<script>
$(function () {
$(".act-but").on("click", function () {
let acnt = $("#acnt").val();
let pswd = $("#pswd").val();
if (acnt && pswd){
$.post('login',
{
acnt: acnt,
pswd: pswd
},
function (data) {
console.log(data);
switch (data) {
case '-1':
alert("用户不存在!");
break;
case '0':
alert("密码错误!");
break;
case '1':
window.location.href='admin.html';
break;
}
}
);
} else {
alert("请输入用户名及密码!");
}
});
})
</script>

 

Node.js部分代码:

var express = require('express');
var router = express.Router();
var bodyPaeser =require('body-parser');
var mysql=require('mysql');
var db=mysql.createConnection({
host:"localhost",
user:"root",
password:"123456",
database: 'web'
});
db.connect(function(err){
if(err){
console.log('[query] - :'+err);
return;
}
console.log('mysql connection succeed');
}
);

router.post('/login', function (req, res) {
let acnt = req.body.acnt;
let pswd = req.body.pswd;
//let code = checkUser(acnt, pswd);
db.query('select user_name as user_name,password as password from user',function(err,rows)
{
if(err){
console.log('[query] - :'+err);
return;
}
var x=-1;
var i;
var p=rows.length;
for(i=0;i<p;i++)
{    
if(acnt===rows[i].user_name)
{
if(pswd===rows[i].password)
{
x=1;
yonghu=acnt;
break;
}
else{
x=0;
break;
}
}
}
res.writeHead(200, {"Access-Control-Allow-Origin": "http://localhost:63342"});
res.write(String(x));
res.end();
let state;
switch (x) {
case 1:
state = " Success";
break;
default:
state = " Filed";
break;
}
console.log("User: " + acnt + " Pswd: " + pswd + state);
});
});

 

这里前端通过表单提交信息给后台,后台Node.js对应的post函数中第二个参数就是一个回调函数,用于处理前后端交互。而在这个函数内部还存在一个连接数据库的查询函数,即db.query(),这里是因为事先引入了对应的连接mysql数据库的模块,所以在连接建立后可直接调用该模块对应函数,重点是这个query函数,它的内部对应的第一个参数是数据库查询语句,第二个参数便又是一个回调函数,用于处理数据库返回的结果。可见回调函数在Node.js实际开发过程中十分常见,并且有很多情况下是回调里面包含新的回调。

posted @ 2019-12-20 21:17  本·西蒙斯  阅读(9555)  评论(0)    收藏  举报