ES6 Promise的使用方法
Promise
promise 是解决异步编程问题的一种方案
从语法上讲 promise是一个对象 通过这个对象 我们可以获取异步操作的信息
var promise = new Promise((resolve, reject) => {
var random = Math.random();
console.log(random);
setTimeout(() => {
if (random > 0.5) {
resolve({
status: 1,
msg: "响应成功"
});
} else {
reject({
status: 0,
msg: "响应失败"
});
}
}, 1000)
})
调用promise的then方法
promise.then(data => {
console.log(data);
}).catch(error => {
console.log(error);
})
console.log(111);
回调地狱
function print(time, str) {
var promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(str);
}, time)
})
return promise;
}
print(1000, "我是第一层回调").then(data => {
console.log(data);
return print(2000, "我是第二层回调");
}).then(data2 => {
console.log(data2);
return print(2000, "我是第三层回调");
}).then(data3 => {
console.log(data3);
return print(2000, "我是第四层回调");
}).then(data4 => {
console.log(data4);
})
Promise的ajax封装
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 === "get") {
var url = obj.url + "?" + toData(obj.data);
xhr.open(obj.type, url, obj.async);
xhr.send();
} else {
xhr.open(obj.type, obj.url, obj.async);
// 设置请求头
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.send(toData(obj.data));
}
// 处理响应体
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);
}
}
}
})
}
then&catch
- 出于未决定的函数是同步的 会立即执行
- then和catch是异步的 就算promise对象里面没有异步操作 让then方法或者catch立即执行,那么这里两个方法会被加入到事件对列中等待执行
var pro1 = new Promise((resolve, reject) => {
console.log(1);
resolve(1234);
console.log(2);
})
// 在promise对象 是同步代码
console.log(pro1);
// then方法是异步的
pro1.then(data => {
console.log(data);
})
// 说明promise对象里面是同步的操作 then方法和catch方法里面是异步的
var pro = new Promise((resolve, reject) => {
console.log("a");
resolve(1);
})
console.log("b");
pro.then(data => {
console.log(data);
})
console.log("c");
var pro = new Promise((resolve, reject) => {
console.log("a");
setTimeout(function () {
console.log("b");
})
// resolve(1);
resolve(2);
})
console.log("c");
pro.then(data => {
console.log(data);
}).catch(data => {
console.log(data);
})
console.log("d");
确定状态
在未决状态的处理函数中 如果发生未捕获的错误 那么状态就会由pending直接变成rejected状态 并且可以被catch捕获
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);
})
then的返回值
1.如果当前的Promise对象是未决的 得到的Promise对象是被挂起的
2.如果当前的promise对象是已决的 那么就会运行相应的后续函数
var pro1 = new Promise((resolve, reject) => {
// resolve(1);
// reject(1);
// setTimeout(function () {
// reject(1);
// })
})
console.log(pro1); //已决状态
var pro2 = pro1.then(data => data * 3);
console.log(pro2); //未决状态
pro2.then(data => {
console.log(data * 2);
}, err => {
console.log(err * 4);
})
Promise的相关API
var r1 = new Promise((resolve, reject) => {
setTimeout(function () {
resolve("I am the frist");
}, 1000)
})
var r2 = new Promise((resolve, reject) => {
setTimeout(function () {
resolve("I am the two");
}, 3000)
})
var r3 = new Promise((resolve, reject) => {
setTimeout(function () {
resolve("I am the three");
}, 4000)
})
var r4 = new Promise((resolve, reject) => {
setTimeout(function () {
resolve("I am the four");
}, 500)
})
all方法
请求同时发送出去 但是要等到最后一个请求返回以后 统一处理数据
Promise.all([r1, r2, r3, r4]).then(data => {
console.log(data);
})
race 方法
请求同时发送出去 谁先回来 就是用谁的数据
Promise.race([r1, r2, r3, r4]).then(data => {
console.log(data);
})
async和await
async和await 是ES7提出来的 作用 和promise一样 解决异步问题 但是他的好处在于 让异步代码和同步的一样
注意点 :
-
同步方法我们拿到结果 是通过返回值
-
异步方法拿到结果 是靠回调函数
async 和await使用的基本语法 :
-
就是在普通函数前面加一个async 调用跟普通函数一样
-
async出现使用 一般都要和await配合使用
-
await后面接的就是一个promise对象 await一定是在异步函数中使用的
function test1() {
return new Promise((resolve, reject) => {
console.log(111);
resolve(1);
})
}
function test2() {
return new Promise((resolve, reject) => {
test1().then(data => {
console.log(data);
resolve();
})
})
}
test2();
使用async和await来解决
async function test1(){
console.log(111);
return 1;
}
async function test2(){
console.log(await test1());
}
test2();
回调地狱改写
function print(time,str){
var promise=new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve(str)
},time);
})
return promise;
}
async function test3(){
var res1=await print(2000,"I am NO.1");
console.log(res1);
var res2=await print(2000,"I am NO.2");
console.log(res2);
var res3=await print(2000,"I am NO.3");
console.log(res3);
var res4=await print(2000,"I am NO.4");
console.log(res4);
}
test3();
class继承和generator函数
使用class关键字实现继承 需要使用extends关键字
<script>
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
work() {
console.log("I Love work");
}
}
// 使用class关键字实现继承 需要使用extends关键字
class Student extends Person {
constructor(name, age, type) {
super(name, age);
this.name = name
this.age = age;
this.type = type;
}
}
var s = new Student("Genji", 20, "student");
console.log(s);
s.work();
</script>
什么是generator函数
generator函数其实就是一个状态机 里面封装了多个状态 通过调用next方法返回当前遍历的值
generator函数实际上是一个iterator生成器
作为普通函数 进行调用 name函数就会从头到尾执行一遍 除非遇到return就停止
需求:让函数一段一段的执行 一段执行完之后 由某个时机触发 进行下一个阶段
function love(){
yield "they are fall in love";
console.log("they are married");
console.log("they are divorced");
return "tragic ending"
}
love();