Promsie:
Promise 是ES6中新出来的API
1. 使用:如果一个工具,说自己支持Promise,那么我们就知道,他的回调函数是用.then来写的就可以了
2. 我们自己给别人提供Promise的工具:
Promise,其实是对于回调函数的另一种写法,可以帮助我们避免 回调地狱
那么什么是回调地狱呢?:
1. 代码结构不清晰,可阅读性极差
2. 代码执行的顺序不清晰
Promise可以用来解决上述问题
封装一个支持Promise APi的延时函数:
function timeOut(time){
// Promise 一般来讲,我们说的都是Promise对象
// .then方法就是 promise对象的方法
// 这个函数中就需要返回一个Promise对象
return new Promise(function(resolve, reject){
// resolve是一个函数,调用这个函数,就可以吧当前promise对象标记为 成功
// reject是一个函数,调用这个函数,就可以吧当前promise对象标记为 失败
// promise对象一共有3个状态
// pendding: 挂起,当前promise执行的任务,正在执行中
// fullfilled: 完成, 当前promise对象执行的任务,已经完成,并且是成功状态
// rejected: 完成, 当前promise对象执行的任务,已经完成,并且是失败状态
// promise对象的.then方法中接收到的成功的回调函数,会在当前promise对象处于成功(fullfilled)状态的时候自动执行
// promise对象的.then方法中接收到的失败的回调函数,会在当前promise对象处于失败(rejected)状态的时候自动执行
setTimeout(function(){
// 这个回调函数中,不需要涉及任何具体的业务操作
// 只需要修改当前promise对象的状态即可!!
// resolve和reject在调用的时候,是可以传递数据的,这个数据会最终被传递到成功或者失败的回调函数中
resolve(123)
// resolve();
// reject(111);
}, time);
});
}
调用封装的函数:
timeOut(1000).then(function(num){
// 成功的时候执行这个函数
console.log("1秒后打印的内容", num); // 1秒后打印的内容 123
}, function(){
// 失败的时候执行这个函数
console.log("promise完成了,但是失败了")
})
也可以这样调用函数(另一种写法):
timeOut(1000).then(function(num){
console.log('成功了', num) // 成功了 123
}).catch(function(){
// catch里面是失败的回调
console.log('失败了')
})
使用promise封装ajax请求:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script>
function ajax(url){
return new Promise(function(resolve, reject){
let xhr = new XMLHttpRequest();
xhr.open("get", url)
xhr.send();
xhr.onreadystatechange = function(){
if(xhr.readyState == 4){
if(xhr.status == 200){
resolve(xhr.responseText);
}else{
reject();
}
}
}
})
}
ajax("http://127.0.0.1:8080/package.json").then(function(res){
console.log("请求成功了", res)
})
</script>
</body>
</html>
Promise其它的api的使用:
function timeOut(time){
return new Promise(function(resolve, reject){
setTimeout(function(){
resolve();
}, time);
});
}
// 我想在5个异步操作全部完成的时候,去做某件事情。
let t1 = timeOut(1000)
let t2 = timeOut(1000)
let t3 = timeOut(1000)
let t4 = timeOut(1000)
let t5 = timeOut(1000)
t1.then(function(){
console.log("我是t1")
})
t2.then(function(){
console.log("我是t2")
})
t3.then(function(){
console.log("我是t3")
})
t4.then(function(){
console.log("我是t4")
})
t5.then(function(){
console.log("我是t5")
})
Promise.all([t1, t2, t3, t4, t5]).then(function(){
console.log("所有异步操作完成了");
})
Promise.race([t1, t2, t3, t4, t5]).then(function(){
console.log("有一个异步率先完成了");
})
// Promise对象有个方法,all方法
// 当所有的被传入的promise全部完成的时候,才会执行这个all的回调
// Promise对象有个方法,race方法
// 当被传入的promise有一个(第一个)完成的时候,就会执行这个race的回调
异步的终极的解决方案:
async await 这个两个关键字 是 es7 中提供的,
可以再将 Promise的写法 进行简化,
async 和 await 必然是同时出现 (有await 必须有async)
function timeOut(time) {
return new Promise(function(resolve, reject) {
setTimeout(function() {
resolve(123);
}, time);
});
}
timeOut(1000).then((num) => {
console.log(num);
});
// async await 这个两个关键字 是 es7 中提供的
// 可以再将 Promise的写法 进行简化
// async 和 await 必然是同时出现 (有await 必须有async)
async function test() {
let num = await timeOut(1000);
console.log('异步代码完成' + num); // 123
}