前端点滴(JS核心)(一)---- 回调函数、Ajax基础(一)

一、回调函数

1. 函数也是对象

JavaScript 中处处皆对象,函数也不例外。
那么如何理解函数也是对象呢?这里主要要表达的是函数也可以使用对象那样的点语法。比如前面学习的Person.prototype;
比如在函数内部,可以使用“函数.length”来表示函数的形参个数,可以使用“函数.name”来获取当前的函数名。

function Person(x,y){
	console.log(Person.length);  //=> 2
	console.log(Person.name);  //=>  Person
}
Person(1,2);

2. 函数也是值

JavaScript 语言将函数看作一种 值,与其它值(数值、字符串、布尔值等等)地位相同。凡是可以使用值的地方,就能使用函数。比如,可以把函数赋值给变量或者对象的属性值,也可以当作参数传入其他函数,或者作为函数的结果返回。函数只是一个可以执行的值,此外并无特殊之处。
由于函数与其他数据类型地位平等,所以在 JavaScript 语言中又称函数为 第一等公民。

/* 当作一个值,赋值给一个变量 */
function a(){
	console.log(1);
}
var b = a;  // 将函数当作一个值,赋值给一个变量
b(); //=> 1

var c = function(){  // 将函数当作一个值,赋值给一个变量
	console.log(1);
}
c(); //=> 1

/* 当作一个对象成员的成员值 */
var obj = {
	name:'chen',
	say:function(){  // 将函数当作一个对象属性的值
		console.log(1);
	}
}
obj.say(); //=> 1

/* 当作一个返回值 */
function fn1(){
var b = 1;
function fn2(){
	console.log(b++);
}
return fn2
}
var fn = fn1();
fn();  //=> 1
fn();  //=> 2
fn();  //=> 3

/* 当作一个参数进行传递 */
function callback(a){ 
	console.log(a);
}
function fn(callback){  // 将函数当作一个参数进行传递(回调函数)
	var a = 1;
	callback(a);
}
fn(callback); //=> 1

3. 函数可以作为参数传递(回调函数)

在JavaScript中,回调函数具体的定义为:函数A作为参数(函数引用)传递到另一个函数B中,并且这个函数B执行函数A。我们就说函数A叫做回调函数。如果没有名称(函数表达式),就叫做匿名回调函数。

来一个具体的实例:

function callback(a){ 
	console.log(a);
}
function fn(callback){
	var a = 1;
	callback(a);
}
fn(callback); //=> 1

其中,下述函数可以称为获取函数(通过参数a,带有获取功能)

function callback(a){ 
	console.log(a);
}

而下述函数被称为资源函数(函数内自带资源,或者通过某些方法获得的资源,通过参数引入获取函数,使得函数与函数间具有通讯功能)

function fn(callback){
	var a = 1;
	callback(a);
}

资源函数中引入获取函数,获取资源

fn(callback);

匿名回调函数
非匿名函数,传递的是函数名的应用。
而匿名函数就是在传参过程中直接传递函数,因为函数可以作为参数传递。

function fn(callback){
	var a = 1;
	callback(a);
}
fn(function (a){console.log(a)})  // 匿名回调函数,回调函数不带名字。

4. 回调函数的执行时机

回调函数,一般在同步情境下是最后执行的,而在异步情境下有可能不执行,因为事件没有被触发或者条件不满足。

5. 回调函数应用

(1)同步中的回调

callback 不一定用于异步,一般同步(阻塞)的场景下也经常用到回调,比如要求执行某些操作后执行回调函数。

同步(阻塞)中使用回调的例子:

var func1=function(callback){
    //do something...(同步任务)
    (callback && typeof(callback) === "function") && callback();
}

var func2=function(){
/* 定义func2 */
	//do something...
}
func1(func2); //fun1执行完后执行fun2

(2)异步中的回调

异步回调的例子:

/* 定时器中使用回调,模拟异步 */
function callback(data){
	if(data.username === 'admin'){
		console.log('验证成功');
	}
}
function fn(callback){
	setTimeout(function(){
		var obj = {
			username:'admin',
			password:123456
		}
		callback(obj)
	},1000)
}
fn(callback)  //=> 1s后,'验证成功' 。

总结:

  • 资源加载:动态加载js文件后执行回调,加载iframe后执行回调,ajax操作回调,图片加载完成执行回调,等异步操作。
  • 事件:DOM事件及Node.js事件基于回调机制 (Node.js回调可能会出现多层回调嵌套的问题)。
  • setTimeout的延迟时间为0,这个hack经常被用到,settimeout调用的函数其实就是一个callback的体现
  • 链式调用:链式调用的时候,在赋值器(setter)方法中(或者本身没有返回值的方法中)很容易实现链式调用,而取值器(getter)相对来说不好实现链式调用,因为你需要取值器返回你需要的数据而不是this指针,如果要实现链式方法,可以用回调函数来实现【不太能理解】
  • setTimeout、setInterval的函数调用得到其返回值。由于两个函数都是异步的,即:他们的调用时序和程序的主流程是相对独立的,所以没有办法在主体里面等待它们的返回值,它们被打开的时候程序也不会停下来等待,否则也就失去了setTimeout及setInterval的意义了,所以用return已经没有意义,只能使用callback。【不太理解】callback的意义在于将timer执行的结果通知给代理函数进行及时处理。

二、Ajax

前言

下载 wampserverapache 服务器。
下载 postman 请求抓包工具

安装方法:
参考:https://blog.csdn.net/qq_34195507/article/details/94851028
参考:https://blog.csdn.net/weixin_43738701/article/details/86607148

Ajax 概述

1. 什么是 Ajax

Ajax中的第一个A是Asynchronous [eɪˈsɪŋkrənəs]
(异步)JavaScript and XML的缩写。可以看出它不是一种技术,而是多种技术的综合体。
其中有JavaScript、有xml、有json、有html、有css、有dom、有XMLHttpRequest对象等等。
XMLHttpRequest对象,也叫做Ajax对象,浏览器中自带的对象。
Ajax的工作也是基于http协议的,用于传输。

2. Ajax 能做什么

  • 从服务器中加载资源、上传资源到服务器。
  • 提高用户的体验。
  • 表单的验证。
  • 引入百度地图、谷歌地图。
  • 网页版的聊天室。
  • 无刷新分页。

3. Ajax 工作原理

在这里插入图片描述
1)创建Ajax 对象 var xhr = new XMLHttpRequest();
2)准备发送资源以及发送地址,请求方式,确定同步发送还是异步发送。
3)调用open() 方法对资源进行发送xhr.open('请求方法','请求地址',同步或异步)
4)监听服务器返回的结果xhr.onreadystatechange = function(){/* 监听函数 */}
5)发送请求,调用Ajax 对象的send() 方法。xhr.send()

4. 主要成员属性以及方法

属性:

  • readyState:表示xhr 工作到何种情况。
  • onreadystatechange:事件,表示 readyState 改变时触发的事件。
  • status:http 状态码。
  • responseText:用来接收返回的文本类型的数据
  • responseXML:用来接收返回的是XML格式的数据

方法:

  • open():设置(定义)一个请求,比如(get请求、post请求…)
  • send():发送设置好的请求,还可以用来发送请求资源。
  • setRequestHeader():设置ajax请求头信息

5. Ajax 的基本使用

完成验证用户名案例,要求用户名唯一,就是不能有重复。
页面中有一个文本框,当失去焦点的时候,验证输出的内容是否已经存在。
HTML

<input type="text" name="username" id="username"> <span id="msg"></span>

JS

/* GET请求 */
document.getElementById('username').onblur = function(){
	/* 1.创建Ajax 对象实例 */
	var xhr = new XMLHttpRequest();
	/* 2.准备发送资源 */
	var uname = this.value;
	/* 3. 备发送资源以及发送地址,请求方式,确定同步发送还是异步发送*/
	/* 注意:发送get请求,资源写在请求路径上以 ?连接 */
	xhr.open('get','checkusername.php?u='+uname,true);
	/* 4.发送请求 */
	xhr.send();
	/* 5.监听服务器返回的结果 */
	xhr.onreadystatechange = function(){
		if(xhr.readyState == 4&& xhr.status == 200){
			/* 处理返回的结果 */
			var res = xhr.responseText;
			if(res == 1){
				document.getElementById('msg').innerHTML = '<font color="red">sorry,用户名已存在</font>'
			}else{
				document.getElementById('msg').innerHTML = '<font color="green">恭喜用户成功</font>'
			}
		}
	}
}

PHP

/* checkusername.php */
/* 后台服务器进行逻辑判断 */
<?php
$arr = ['zhangsan','lishi','wangwu'];
$u = $_GET['u'];
if(in_array($u,$arr)){
	echo 1;
}else{
	echo 0;
}
>

注意点:

  • 用get方式请求,所以参数直接写到url上即可。服务器端获取地址栏的参数,同样使用$_GET来获取。
  • 接受服务器返回的数据时要对Ajax进程进行监听。

如果没有进行Ajax 进程监听,无法得到服务器返回的数据。

/* GET请求 */
document.getElementById('username').onblur = function(){
	var xhr = new XMLHttpRequest();
	var uname = this.value;
	xhr.open('get','checkusername.php?u='+uname,true);
	xhr.send();
	var res = xhr.responeText;
	console.log(res);          //=>  无法获取返回数据
		if(res == 1){
			document.getElementById('msg').innerHTML = '<font color="red">sorry,用户名已存在</font>'
		}else{
			document.getElementById('msg').innerHTML = '<font color="green">恭喜用户成功</font>'
		}
	}

原因就是因为Ajax 请求存在过程问题,由于send()后数据进行传输,如果传输数据过大需要的时间就越长,而JavaScript并不会等待有数据了它才返回(异步问题)。所以需要监听Ajax 进程,当Ajax 进程发生改变就调用事件,当 readyState==4时表示数据接收完毕可以通过某些方法属性返回数据了。
在这里插入图片描述

6. 细节问题

(1)对字符进行编码

默认情况下传输数据是什么,url 上的地址拼接就是什么。
例如上代码的输出:
在这里插入图片描述
解决的办法就是对用户输入的内容进行编码。

  • encodeURI() — 不能对“:/=&”进行编码,能对汉字进行编码
  • encodeURIComponent() — 能对“:/=&”进行编码,也能对汉字进行编码

在这里插入图片描述
一般情况下,JS编码后发送到服务器,PHP会自动解码,如果没有自动解码,用PHP的函数urldecode来解码。

(2)缓存处理

什么是Ajax缓存原理?
Ajax在发送的数据成功后,会把请求的URL和返回的响应结果保存在浏览器缓存内,当下一次调用Ajax发送相同的请求时,它会直接从缓存中把数据取出来,这是为了提高页面的响应速度和用户体验。当前这两次请求URL完全相同,包括参数。这个时候,浏览器就不会与服务器交互。
两次请求的地址完全一致(包括参数),那么IE就会从缓存中取服务器上一次返回的结果。而不会从新向服务器发送请求。

在这里插入图片描述
如何解决IE缓存的问题:

  1. 在ajax对象.send()前加上 xhr.setRequestHeader("If-Modified-Since","0"); //实测可用
  2. 在服务器端加
    header("Cache-Control:no-cache");
    header("Pragma:no-cache");
    header("Expires:-1");
    加入三个header,目的是让所有的浏览器都不缓存。
  3. Ajax 的 URL 参数后加上 "?fresh=" + Math.random()//当然这里参数 fresh 可以任意取了
  4. 第种方法和第3种类似,在 URL 参数后加上 "?timestamp=" + new Date().getTime()
  5. 使用POST 请求替代GET 请求。

7. Ajax 中使用GET请求与POST请求的区别

在这里插入图片描述
请求写法上的区别:

区别一:请求方式不同。
区别二:GET请求将传递参数写在请求地址中(与地址拼接),POST请求则将参数放入send()中进行发送。
区别三:POST 请求需要设置请求头。
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
区别四:服务器端用$_GET对GET请求参数进行获取,使用$_POST对POST请求参数进行获取。

本质区别:

参考博客:https://blog.csdn.net/Errrl/article/details/103467472

对ajax中的get和post的一些说明:

①、用post请求,不会产生缓存。
②、用post请求的时候,能不能也用get,即post和get请求同时使用。答案是能,只不过get请求的参数用$_GET获取,post请求的参数用$_POST获取。
③、用$_REQUEST获取get和post方式提交的参数,如果参数名相同,获取的是谁?获取的是post的内容。

8. Ajax 中的同步与异步说明

同步请求,在同一个时间点上,只能有一个进程;其他进程只能等待。
异步请求,在同一个时间点上,可以同时进行多个进程。
open方法的第三个参数表示同步或者是异步请求。默认值true表示异步请求,false表示同步请求。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值