本文章有使用提到的ajax案例进行promise封装
1. 常见异步操作:
使用回调函数实现:
1.AJAX请求
2.fs文件操作
3.数据库操作
4.定时器
2. ajax
ajax使用案例
const btn=document.querySelector('.xx');
//定义 点击事件 去触发 ajax 请求
btn.addEventListener('click',function(){
//1.创建对象
const xhr = new XMLHttpRequest();
//可以设置响应结果的类型
xhr.responseType = 'json'
//2.初始化
xhr.open('GET','https://localhost:8080/login');
//3.发送
xhr.send();
//4.处理响应结果(使用回调函数)
xhr.onreadystatechange = function (){
if(xhr.readyState === 4){
//认定状态码200~300为成功时:
if(xhr.status>=200 && xhr.status <300){
//控制台输出响应体
console.log(xhr.response)
}else{
console.log(xhr.status)
}
}
}
})
3. promise
是JS中进行异步编程的 新解决方案
旧方案:单纯使用回调函数。
语法:构造函数。可以实例化对象,封装异步操作,获取成功或失败的结果
promise的状态
返回promise对象时,实例对象的属性:promiseState
其值是:
- pending 未决定的;
- resolved / fulfilled 成功 ;
- rejected 失败 ;
一个promise对象只能改变一次
:不改变状态不执行then回调,改变状态后执行then回调.
状态改变只能是函数resolve、reject、throw,状态变化为:pending ->resolved 或者 pending ->rejected
promise对象的值
返回promise对象时,实例对象的另一个属性:promiseResult
其值是:保存着对象 成功/失败 的结果
函数resolve、reject 可以对该属性值进行操作,promiseResult保存对应函数的参数值
promise执行过程简述:
let p = new promise((resolve,reject)=>{
// resolve、reject、throw 来改变状态
}).then(
//回调函数
(value)=>{
},(reason)=>{
})
1.指定回调->改变状态->执行回调
2.改变状态->指定回调->执行回调
promise优势:
指定回调函数方式更灵活
支持链式调用,可以解决回调地狱问题:
回调地狱:嵌套调用,外部回调函数异步执行的结果是嵌套回调执行的条件
缺点:不便于阅读,不便于异常处理
promise使用案例
//resolve 函数类型的数据 成功调用 将promise对象状态设置为成功
//reject 函数类型的数据 失败调用 将promise对象状态设置为失败
const p = new Promise((resolve,reject)=>{
//以fs文件操作为例子
fs.readFile('./content.txt',(err,data)=>{
//失败时调用
if(err) reject(err);
//成功时调用
resolve(data);
})
});
p.then(
//状态为 成功 时调用
(data) => {
},
//状态为 失败 时调用
(err) => {
}).
封装上面ajax案例
const btn=document.querySelector('.xx');
//定义 点击事件 去触发 ajax 请求
btn.addEventListener('click',function(){
const p = new Promise((resolve,reject)=>{
//1.创建对象
const xhr = new XMLHttpRequest();
//2.初始化
xhr.open('GET','https://localhost:8080/login');
//3.发送
xhr.send();
//4.处理响应结果
xhr.onreadystatechaenge = function (){
if(xhr.readyState === 4){
//认定状态码200~300为成功时:
if(xhr.status>=200 && xhr.status <300){
//控制台输出响应体
resolve(xhr.response)//传递值
}else{
reject(xhr.status)//传递值
}
}
}
})
//调用then方法
p.then(
//状态为 成功 时调用,value是resolve传出来的值
(value) => {
console.log(value)},
//状态为 失败 时调用,reason是reject传出来的值
(reason) => {
console.log(reason)});
})
封装ajax案例
function get(url){
return new Promise((resolve,reject)=>{
//1.创建对象
const xhr = new XMLHttpRequest();
//2.初始化
xhr.open('GET',url);
//3.发送
xhr.send();
//4.处理响应结果
xhr.onreadystatechaenge = function (){
if(xhr.readyState === 4){
//认定状态码200~300为成功时:
if(xhr.status>=200 && xhr.status <300){
//控制台输出响应体
resolve(xhr.response)
}else{
reject(xhr.status)
}
}
}
})
//发送请求
get('https://localhost:8080/login')
.then(
//状态为 成功 时调用
(value) => {
console.log(value)},
//状态为 失败 时调用
(reason) => {
console.log(reason)});
}
4. 其他有关promise
async、async
async 一般用于修饰返回promise对象的函数
await 修饰promise 对象能直接拿到resolve的值
Promise的函数方法
属于函数对象不属于实例对象,即直接使用:Promise.方法名(参数)
(1)Promise.resolve方法(value)=>{}
参数value:成功数据或者promise对象
返回一个成功、失败的promise对象
(2)Promise.reject方法 (reason)=>{}
参数reason:失败的原因
返回一个失败的promise对象
(3)Promise.all方法 (promise)=>{}
参数promise:包含n个promise数组
返回一个新的promise对象,所有成功即成功
(4)Promise.race方法 (promise)=>{}
参数promise:包含n个promise数组
返回一个新的promise对象,第一个完成的状态是最终状态
let p1 = new promise((resolve,reject)=>{
resolve('OK1') //成功
})
let p2 = Promise.resolve('OK2') //成功
let p3 = Promise.reject('error3') //失败
let p4 = Promise.all([p1,p2,p3]) //失败
let p4 = Promise.race([p1,p2,p3]) //成功