ES6 Promise函数
一、promise函数是干什么的
promise函数是解决异步编程调用代码逻辑编写过于复杂的问题的,当网络请求非常复杂时,就会出现回调地狱,这样如果将这些代码写在一起就会看起来很复杂,且不利于阅读,如果用promise的话就会让代码看起来更加美观优雅
二、Promise三种状态
首先, 当我们开发中有异步操作时, 就可以给异步操作包装一个Promise
异步操作之后会有三种状态
pending:等待状态,比如正在进行网络请求,或者定时器没有到时间。
fulfill:满足状态,当我们主动回调了resolve时,就处于该状态,并且会回调.then()
reject:拒绝状态,当我们主动回调了reject时,就处于该状态,并且会回调.catch()
三、实现
1,then和catch
1.出于未决状态的函数是同步的 会立即执行
2.then和catch是异步的 就算promise对象里面没有异步操作 让then方法或者catch立即执行 那么 这里两个方法或被加入到事件队列中等待执行
//参数 函数(resolve,reject)
new Promise((resolve, reject) => {
setTimeout(() => {
//请求成功的时候调用resolve
resolve('22222')
//请求失败的时候调用reject
reject('error message')
}, 1000)
}).then((data) => { //请求成功处理函数
console.log(data)
}).catch((err) => { //请求失败处理函数
console.log(err)
})
2.确定状态
- 在未决状态的处理函数中 如果发生未捕获的错误呀 那么状态就会有pending 直接变成 rejected状态 并且可以被catach捕获
var pro = new Promise((resolve, reject) => {
throw new Error("123");
// try{
// throw new Error("123");
// } catch(e) {}
resolve(12);
reject(34);
})
// pro.then(data => {
// console.log(data);
// }, err => {
// console.log(err);
// })
console.log(pro);
pro.then(data => {
console.log(data);
})
pro.catch(data => {
console.log(data);
})
3.async和await
1.使用Promise:
const makeRequest = () =>
getJSON().then(data => {
console.log(data)
return "done"
})
makeRequest()
2.使用Async:
async和await 是ES7提出来的
async作用: 简化函数返回值中promise对象的创建
一般情况下, async写在函数的最前面,被修饰的函数的返回值 ,一定是promise对象。只有在某些特殊情况下 才会手动返回一个promise对象。
作用:和promise一样 解决异步问题 但是他的好处在于 让异步代码和同步的一样!!
注意点 : 同步方法我们拿到结果 是通过返回值,异步方法拿到结果,是靠回调函数。
async 和await使用的基本语法 :
- 就是在普通函数前面加一个async 调用跟普通函数一样
- async出现使用 一般都要和await配合使用
- await后面接的就是一个promise对象 await一定是在异步函数中使用的
const makeRequest = async () => {
// await getJSON()表示console.log会等到getJSON的promise成功reosolve之后再执行。
console.log(await getJSON)
return "done"
}
makeRequest()
3.区别
1.函数前面多了一个aync关键字。await关键字只能用在aync定义的函数内。async函数会隐式地返回一个promise,该promise的reosolve值就是函数return的值。(示例中reosolve值就是字符串”done”)
2.我们不能在最外层代码中使用await,因为不在async函数内。
四.promise方法
var r1 = new Promise((resolve,reject) => {
setTimeout(function(){
resolve("我是第一个请求");
},1000)
})
var r2 = new Promise((resolve,reject) => {
setTimeout(function(){
resolve("我是第二个请求");
},3000)
})
var r3 = new Promise((resolve,reject) => {
setTimeout(function(){
resolve("我是第三个请求");
},4000)
})
var r4 = new Promise((resolve,reject) => {
setTimeout(function(){
resolve("我是第四个请求");
},500)
})
1.all方法
有时候我们需要等待两个或者多个请求都成功返回了再进行下一步操作,promise 的all方法是等所有的异步请求完成之后在进行下一步回调
Promise.all([r1,r2,r3,r4]).then(data => {
console.log(data);
})
2.race方法
请求同时发送出去 谁先回来 就是用谁的数据。
Promise.race([r1,r2,r3,r4]).then(data => {
console.log(data);
})
五.promise封装ajax案例
<script>
function toData(obj) {
// 声明一个数组 来装每一组的数据
var arr = [];
if(obj !== null) {
for(var key in obj) {
let str = key + "=" + obj[key];
arr.push(str);
}
return arr.join("&");
}
}
function ajax(obj) {
return new Promise(function(resolve, reject) {
// 给ajax所需要的参数设置默认值
obj.type = obj.type || "get";
obj.async = obj.async|| "true";
obj.dataType = obj.dataType || "json";
obj.data = obj.data || null;
// 开始发送ajax请求
var xhr;
if(window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
} else {
// IE低版本的浏览器
xhr = new ActiveXObject("Microsoft.XMLHttp");
}
// 判断是post请求 还是get请求
if(obj.type === "post") {
xhr.open(obj.type, obj.url, obj.async);
// 设置请求头
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send(toData(obj.data));
} else {
var url = obj.url + "?" + toData(obj.data);
xhr.open(obj.type, url, obj.async);
xhr.send();
}
// 处理响应体
xhr.onreadystatechange = function() {
if(xhr.readyState == 4) {
if(xhr.status >= 200 && xhr.status < 300 || xhr.status == 304) {
resolve(JSON.parse(xhr.responseText));
} else {
reject(xhr.status);
}
}
}
})
}
ajax({
url : "./data.php",
data : {
name : "jack",
age : 16
}
}).then(res => {
console.log(res);
}, err => {
console.log(err);
})
</script>
思路都注释在代码上了,嘻嘻嘻,如果有错误就麻烦指出来哦!!!