AJAX即“Asynchronous Javascript And XML”
异步js 和(xml)一般指可扩展标记语言
是指一种创建交互式网页应用的网页开发技术
可以令开发者只向服务器获取数据
Ajax是一种异步请求数据的web开发技术
Response 响应,回答,回复
fetch 拿来,取来
AJAX是个大类,相当于一个技术的总称
XMLHttpRequest 是个api
其下有xhr API ,fetch API,其他API
http与ajax的区别
两者本质区别:
- AJAX通过xmlHttpRequest对象请求服务器服务器接受请求返数据实现刷新交互
- 普通http请求通过httpRequest对象请求服务器接受请求返数据需要页面刷新
AJAX请求头会多一个x-requested-with参数,值为XMLHttpRequest
Ajax与websocket、http:其实这三者各有优缺点,websocket、ajax的出现解决的http协议的一些问题,但http依然在很多地方是好的有优势的,ajax是单向(客户端到服务端),http也是单向由客户端发起的,websocket实现了双向,但他们各自有自己适合的使用场景。
“axios是对 xhr的封装,本质就是 ajax 请求,只是调用起来更方便。
if (window.XMLHttpRequest)
{// 兼容 IE7+, Firefox, Chrome, Opera, Safari
xhr=new XMLHttpRequest();
} else{// 兼容 IE6, IE5
xhr=new ActiveXObject("Microsoft.XMLHTTP");
}
请求之后服务器会响应处理
分同步处理 异步处理两种。
responseText 获得字符串形式的响应数据。
responseXML 获得XML 形式的响应数据。(jquery 用的这个)
xhr.open("GET","info.txt",false); //同步处理
xhr.send();
document.getElementById("myDiv").innerHTML=xhr.responseText; //获取数据直接显示在页面上
异步要在请求状态改变事件中处理。
HTTP状态码(status)由三个十进制数字组成,第一个十进制数字定义了状态码的类型,后两个数字没有分类的作用。HTTP状态码共分为5种类型
常见的状态码
常见四种请求
get 通常用来请求某条数据或是一个数组的列表数据,参数会放在地址栏进行传输,常见的大部分请求都是get请求
缺点: 因为参数放在地址栏上,所以不安全,一般get请求会发送一些对安全性不高的数据请求,像登录注册相关的请求不会采用get请求
地址栏的长度是有限制的,大概2kb左右
post 比较安全,参数放在请求的body体中的,传输的数据量很大,跟表单提交的一般都是post请求.登录,注册,新建一般都是post
put 和post一样,参数和数据都一样,一般用作修改数据
delete 和get一样,参数一样,一般用作删除数据
post和get的区别牵扯到http协议 tcp-ip协议,请求头,请求体相关的知识,后面在看
由于 Fetch API 是基于 Promise 设计,有必要先学习一下 Promise
https://segmentfault.com/a/1190000003810652
resolve 表决 决定,解决
reject 拒绝
JSON.stringify() 方法用于将 JavaScript 值转换为 JSON 字符串。
toString()
方法返回一个表示该对象的字符串。
安装的包叫依赖,configdev是环境
Promise
Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。
Promise的构造函数接收一个参数:函数,并且这个函数需要传入两个参数:
- resolve :异步操作执行成功后的回调函数
- reject:异步操作执行失败后的回调函数
Promise对象,Promise实例
executor 执行人
pendding 悬挂
require 依赖
promise相当于一个状态机 有三种状态:
-
pending 等待态
-
fulfilled 执行态 实现,履行,执行
-
rejected 拒绝态
(1) promise 对象初始化状态为 pending
(2) 当调用resolve(成功),会由pending => fulfilled
(3) 当调用reject(失败),会由pending => rejected
Promise 实例具有then
方法,
then方法是定义在原型对象Promise.prototype上的。它的作用是为 Promise 实例添加状态改变时的回调函数。前面说过,then方法的第一个参数是resolved状态的回调函数,第二个参数是rejected状态的回调函数,它们都是可选的。
//catch 集体捕获错误
promise.then(() => {}).then(() => {}).catch(() => {})
// 不需要再每一个then里面都加上失败函数,可以选择在最后加上catch,如果失败或报错直接走到这
当一个 Promise 的状态被 fulfilled 之后,会执行其回调函数,而回调函数返回的结果会被当作 value,返回给下一个 Promise(也就是then 中产生的 Promise),同时下一个 Promise的状态也会被改变(执行 resolve 或 reject),然后再去执行其回调,以此类推下去...链式调用的效应就出来了。
真正的链式Promise是指在当前promise达到fulfilled状态后,即开始进行下一个promise.
Promise.prototype.catch,在链式写法中可以捕获前面的异常
Promise.resolve,返回一个fulfilled状态的promise对象
Promise.reject,返回一个rejected状态的promise对象
Promise.all,接收一个promise对象数组为参数 只有全部 promise 进入 fulfilled 状态才会resolve 通常会用来处理 多个并行异步操作
Promise.race,接收一个promise对象数组为参数 Promise.race 只要有一个promise对象进入 fulfilled 或者 rejected 状态的话,就会继续进行后面的处理
Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。
ES6 规定,Promise对象是一个构造函数,用来生成Promise实例。
Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject。它们是两个函数,由 JavaScript 引擎提供,不用自己部署。
then方法可以接受两个回调函数作为参数。第一个回调函数是Promise对象的状态变为resolved时调用,第二个回调函数是Promise对象的状态变为rejected时调用。其中,第二个函数是可选的,不一定要提供。这两个函数都接受Promise对象传出的值作为参数。
Promise是一个构造函数,自己身上有all、reject、resolve这几个眼熟的方法,原型上有then、catch等同样很眼熟的方法。
注意!我只是new了一个对象,并没有调用它,我们传进去的函数就已经执行了,这是需要注意的一个细节。所以我们用Promise的时候一般是包在一个函数中,在需要的时候去运行这个函数
执行这个函数我们得到了一个Promise对象
Promise对象上有then、catch方法 后面可以用传过来的数据做些其他操作
then里面的函数就跟我们平时的回调函数一个意思,能够在runAsync这个异步任务执行完成之后被执行
能把原来的回调写法分离出来,在异步操作执行完后,用链式调用的方式执行回调函数。
Promise的优势在于,可以在then方法中继续写Promise对象并返回,然后继续调用then来进行回调操作。解决回调地狱问题。
实质上,Promise的精髓是“状态”,用维护状态、传递状态的方式来使得回调函数能够及时调用,它比传递callback函数要简单、灵活的多。
在then方法中,你也可以直接return数据而不是Promise对象,在后面的then中就可以接收到数据了。
reject的作用就是把Promise的状态置为rejected,这样我们在then中就能捕捉到,然后执行“失败”情况的回调。
then方法可以接受两个参数,第一个对应resolve的回调,第二个对应reject的回调,其中,第二个函数是可选的,
,(function(reason, data))
catch方法,做用 其实它和then的第二个参数一样,用来指定reject的回调
(then方法可以指定连个函数,第二个是可选的,如果只写一个回调,就代表成功,后面接catch是失败的回调)
另外一个作用:在执行resolve的回调(也就是上面then中的第一个参数)时,如果抛出异常了(代码出错了),那么并不会报错卡死js,而是会进到这个catch方法中
getNumber()
.then(function(data){
console.log('resolved');
console.log(data);
console.log(somedata); //此处的somedata未定义
})
.catch(function(reason){
console.log('rejected');
console.log(reason);
});
在resolve的回调中,我们console.log(somedata);而somedata这个变量是没有被定义的。如果我们不用Promise,代码运行到这里就直接在控制台报错了,不往下运行了。但是在这里,会得到这样的结果:
进到catch方法里面去了,把错误原因传到了reason参数中。即便是有错误的代码也不会报错了,这与我们的try/catch语句有相同的功能。
all的用法
all方法提供了并行执行异步操作的能力,并且在所有异步操作执行完后才执行回调
all接收一个数组参数,里面的值最终都算返回Promise对象
三个异步操作的并行执行的,等到它们都执行完后才会进到then里面。
三个异步操作返回的数据 都在then里面,all会把所有异步操作的结果放进一个数组中传给then,就是上面的results。
有了all,你就可以并行执行多个异步操作,并且在一个回调中处理所有的返回数据
使用场景:所有的静态资源都加载完后,我们再进行页面的初始化。
只要数组元素:p1
、p2
、p3
之中有一个被rejected
,p
的状态就变成rejected
,此时第一个被reject
的实例的返回值,会传递给p
的回调函数。
all方法的效果实际上是「谁跑的慢,以谁为准执行回调」
race
「谁跑的快,以谁为准执行回调」,这就是race方法,这个词本来就是赛跑的意思
这三个异步操作同样是并行执行的。
这个race有什么用呢?使用场景还是很多的,比如我们可以用race给某个异步请求设置超时时间,并且在超时后执行相应的操作。
于是他俩就会赛跑,如果5秒之内图片请求成功了,那么遍进入then方法,执行正常的流程。如果5秒钟图片还未成功返回,那么timeout就跑赢了,则进入catch,报出“图片请求超时”的信息。
https://es6.ruanyifeng.com/#docs/promise#Promise-prototype-finally
finally用法
finally()方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。
不管promise最后的状态,在执行完then或catch指定的回调函数以后,都会执行finally方法指定的回调函数
下面是一个例子,服务器使用 Promise 处理请求,然后使用finally
方法关掉服务器
finally
本质上是then
方法的特例。
不管前面的 Promise 是fulfilled
还是rejected
,都会执行回调函数callback
。
ES6-生成器(generator)
ES6-生成器(generator)_Aproducer的博客-CSDN博客
Generator 函数是一个状态机,封装了多个内部状态。
执行 Generator 函数会返回一个遍历器对象,也就是说,Generator 函数除了状态机,还是一个遍历器对象生成函数。返回的遍历器对象,可以依次遍历 Generator 函数内部的每一个状态。
它会依次执行里面定义的状态,用.next()方法
function* gen(){
for(let i=0;i<3;i++){
yield 'i'+i;
}
}
let a=gen();
console.log(a);
console.log(a.next());
console.log(a.next());
console.log(a.next());
console.log(a.next());
换言之,Generator 函数是分段执行的,yield
表达式是暂停执行的标记,而next
方法可以恢复执行。
ES6 没有规定,function
关键字与函数名之间的星号,写在哪个位置。这导致下面的写法都能通过。
function * foo(x, y) { ··· }
function *foo(x, y) { ··· }
function* foo(x, y) { ··· } //常用
function*foo(x, y) { ··· }
Generator 函数返回的遍历器对象,只有调用next
方法才会遍历下一个内部状态,所以其实提供了一种可以暂停执行的函数。yield
表达式就是暂停标志
相似之处在于,都能返回紧跟在语句后面的那个表达式的值。区别在于每次遇到yield
,函数暂停执行,下一次再从该位置继续向后执行,而return
语句不具备位置记忆的功能。一个函数里面,只能执行一次(或者说一个)return
语句,但是可以执行多次(或者说多个)yield
表达式。
yield
表达式只能用在 Generator 函数里面,用在其他地方都会报错。
yield
表达式如果用在另一个表达式之中,必须放在圆括号里面。
ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。
Set
本身是一个构造函数,用来生成 Set 数据结构。JavaScript 的对象(Object),本质上是键值对的集合(Hash 结构),但是传统上只能用字符串当作键
ES6 提供了 Map 数据结构。它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键
next 方法的参数
yield
表达式本身没有返回值,或者说总是返回undefined
。next
方法可以带一个参数,该参数就会被当作上一个yield
表达式的返回值。
async 函数是什么?
一句话,它就是 Generator 函数的语法糖。前文有一个 Generator 函数,依次读取两个文件。
可以让异步的函数等待异步执行的结果出来再继续往下进行。
async是一个加在函数前的修饰符,被async定义的函数会默认返回一个Promise对象resolve的值。因此对async函数可以直接then,返回值就是then方法传入的函数。