# ajax与promise

# ajax
AJAX 全称为Asynchronous JavaScript And XML，就是异步的JS 和XML
通过AJAX 可以在浏览器中向服务器发送异步请求，最大的优势：无刷新获取数据

# 优缺点
优点：
可以无需刷新页面而与服务器端进行通信。
允许你根据用户事件来更新部分页面内容。

缺点：
没有浏览历史，不能回退。
存在跨域问题(同源)。
SEO 不友好。

# ajax核心对象使用步骤
~~~
// 1.创建XMLHttpRequest 对象
let xhr = new XMLHttpRequest();
// 2.设置请求信息（请求方法和url）
// 请求方式
xhr.open(method, url);
//可以设置请求头，一般不设置
xhr.setRequestHeader('Content-Type', 'application/json');
// 3.发送请求
xhr.send(body) //get请求不传 body 参数，只有post请求使用
// 4.接收响应（事件绑定，处理服务端返回的结果）
//xhr.responseXML 接收 xml格式 的响应数据
//xhr.responseText 接收 文本格式 的响应数据
xhr.onreadystatechange = function (){
	// readyState 是 xhr对象中的属性, 表示状态 0 1 2 3 4
	if(xhr.readyState == 4 && xhr.status == 200){
		var text = xhr.responseText;
		console.log(text);
	}
}
~~~

MDN文档链接：[https://developer.mozilla.org/zh-CN/docs/Web/Guide/AJAX](Link)

文章链接：[https://blog.csdn.net/weixin_44972008/article/details/113772348](Link)

# Promise 是什么？
- 是解决异步编程的一种新方案
- 语法上是一个构造函数
- 功能上 promise对象用来封装一个异步操作并可以获取其结果
- 支持链式调用，可以解决回调地狱(多层嵌套)

MDN文档：[https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise](Link)

# 实例对象与函数对象
- 实例对象：new 函数产生的对象，称为实例对象，简称为对象
- 函数对象：将函数作为对象使用时，称为函数对象
~~~
function Fn(){}
// fn为实例对象(简称对象)  Fn为构造函数
let fn = new Fn()
// Fn为函数对象(作为对象使用)
Fn.prototype
// Fn为函数对象
Fn.call({})
~~~

# 同步回调与异步回调
同步回调 立即执行，完全执行完了才结束，不会放入回调队列中
例如：数组遍历相关的回调 / Promise的executor函数
~~~
new Promise((res,rej)=>{
  // executor函数
  // 同步调用
})
~~~
异步回调 不会立即执行，会放入回调队列中将来执行
例如：定时器回调 / ajax回调 / Promise成功或失败的回调(then方法中的回调函数)

# 同步>微队列>宏对列
1. js中用来储存待执行回调函数的队列包含2个不同待定的队列
2. 宏队列：用来保存待执行的宏对列(回调)，比如：定时器/dom事件回调/ajax回调
3. 微队列：用来保存待执行的微对列(回调)，比如：promise回调/mutationObserver的回调
4. js执行时会区别这两个队列
        js引擎首先必须先执行所有的初始化同步代码
        每次准备取出第一个宏任务执行前，都要将所有的微任务一个一个取出来执行


# Promise静态方法
Promise.resolve((value)=>{})
~~~
// 如果传入参数为非promise类型的对象，返回结果为成功的promise对象
let p1 = new Promise.resolve(123)
// 如果传入参数为promise对象，参数的结果则为reslove的结果
let p2 = new Promise.resolve(new Promise((res,rej)=>{}))
~~~
返回一个成功/失败的promise对象

Promise.reject((error)=>{})
~~~
let p1 = Promise.reject(123)
~~~
error:失败原因
返回一个失败的promise对象

Promise.all(promises)
~~~
let p1 = new Promise((res,rej)=>{})
let p2 = Promise.resolve()
let p3 = Promise.reject()
let p4 = Promise.all([p1,p2,p3])
~~~
promises:包含多个promise的数组
返回一个新的promise对象，只有所有promise都成功才成功，只要有一个失败就直接失败

Promise.race(promises)
~~~
let p1 = new Promise((res,rej)=>{})
let p2 = Promise.resolve()
let p3 = Promise.reject()
let p4 = Promise.race([p1,p2,p3])
~~~
promises:包含多个promise的数组
返回一个新的promise对象，第一个完成的promise的结果状态就是最终的结果状态

then方法返回的Promise的结果，由参数中的返回的Promise的状态决定

中断Promise链式调用，有且只有一种，返回pending状态下的Promise对象
~~~
let p1 = new Promise((res, rej) => {
  res(1);
});
p1.then((res) => {
  // 中断链式调用
  return new Promise(() => {});
}).then((res) => {});
~~~

# asnc与await
async 函数
函数的返回值为promise对象
promise对象的结果有async函数执行的返回值决定
await 表达式
await右侧的表达式一般为promise对象，但也可以是其他值
如果表达式是promise对象，await返回的是promise成功的值
如果表达式是其他值，直接将此值作为await的返回值
注意
await必须写在async函数中，但async函数中可以没有await
如果await的promise失败了，就会抛出异常，需要通过try catch来捕获处理





