实例对象、函数对象、回调等相关知识参考:这个
Promise简介
- Promise是一门新的技术(ES6规范),是JS中进行异步编程的新解决方案(旧方案是单纯使用回调函数)。
- 从语法上看:Promise是一个构造函数(自己身上有all、reject、resolve这几个方法,原型上有then、catch等方法)。
- 从功能上来说: Promise对象用来封装一个异步操作并可以获取其成功/失败的结果值。
- ==异步编程: ①fs 文件操作 ②数据库操作 ③Ajax ④setInterval==
- Promise指定回调函数的方式更加灵活: 旧的: 必须在启动异步任务前指定 promise: 启动异步任务=> 返回promie对象=> 给promise对象绑定回调函数(甚至可以在异步任务结束后指定/多个)
- Promise支持链式调用, 可以解决回调地狱问题(回调函数嵌套调用, 外部回调函数异步执行的结果是嵌套的回调执行的条件)
<script>
//回调地狱
doSomething(function(result){
doSomethingElse(result,function(newResult){
doThirdThing(newResult,function(finalResult){
console.log('Gotthefinalresult:'+finalResult)
},failureCallback)
},failureCallback)
},failureCallback)
//使用promise的链式调用解决回调地狱
doSomething().then(function(result){
return doSomethingElse(result)
})
.then(function(newResult){
return doThirdThing(newResult)
})
.then(function(finalResult){
console.log('Gotthefinalresult:'+finalResult)
})
.catch(failureCallback)
// async/await:回调地狱的终极解决方案
asyncfunctionrequest(){
try{const result=awaitdoSomething()
const newResult=awaitdoSomethingElse(result)
constfinalResult=awaitdoThirdThing(newResult)
console.log('Gotthefinalresult:'+finalResult)
}catch(error){
failureCallback(error)
}
}
</script>
Promise的基本流程
- Promise封装一个异步的操作,在成功时调用resolve并把结果传给resolve函数,失败时调用reject并把失败的原因或错误传给reject函数。
- 然后在then函数里处理成功或失败的结果。成功(结果数据一般称为value)则调用第一个回调函数里的代码,失败(结果数据一般称为reason)则调用第二个回调函数里的代码。
Promise的基本使用
对AJAX操作封装
//创建 Promise
const p = new Promise((resolve, reject) => {
//1.创建对象
const xhr = new XMLHttpRequest();
//2. 初始化
xhr.open('GET', 'https://api.apiopen.top/getJoke');
//3. 发送
xhr.send();
//4. 处理响应结果
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
//判断响应状态码 2xx
if(xhr.status >= 200 && xhr.status < 300){
//控制台输出响应体
resolve(xhr.response);
}else{
//控制台输出响应状态码
reject(xhr.status);
}
}
}
});
//调用then方法
p.then(value=>{
console.log(value);
}, reason=>{
console.warn(reason);
});
对setInterval操作封装
<body>
<div class="container">
<h2 class="page-header">Promise 初体验</h2>
<button class="btn btn-primary" id="btn">点击抽奖</button>
</div>
<script>
//生成随机数
function rand(m,n){
return Math.ceil(Math.random() * (n-m+1)) + m-1;
}
//点击按钮, 1s 后显示是否中奖(30%概率中奖)
const btn = document.querySelector('#btn');
btn.addEventListener('click', function(){
//定时器
// setTimeout(() => {
// //获取从1 - 100的一个随机数
// let n = rand(1, 100);
// if(n <= 30){
// alert('恭喜恭喜, 奖品为 10万 RMB 劳斯莱斯优惠券');
// }else{
// alert('再接再厉');
// }
// }, 1000);
//Promise 形式实现
//1)创建promise对象(pending状态),指定执行器函数
const p = new Promise((resolve, reject) => {
//2)在执行器函数中启动异步任务
setTimeout(() => {
//获取从1 - 100的一个随机数
let n = rand(1, 100);
if(n <= 30){//3.1)如果成功了,调用resolve(),指定成功的value,变为resolved状态,将 promise 对象的状态设置为 『成功』
resolve(n);
}else{//3.2)如果失败了,调用reject(),指定失败的reason,变为rejected状态,将 promise 对象的状态设置为 『失败』
reject(n);
}
}, 1000);
});
console.log(p);
//调用 then 方法
p.then((value) => {//成功的回调函数onResolved,得到成功的vlaue
alert('恭喜恭喜, 奖品为 10万 RMB 劳斯莱斯优惠券, 您的中奖数字为 ' + value);
}, (reason) => {//失败的回调函数onRejected,得到失败的reason
alert('再接再厉, 您的号码为 ' + reason);
});
});
</script>
</body>
</html>
Promise的API
1.Promise 构造函数:Promise(executor) {}
- executor 函数:同步执行 (resolve, reject) => {}
- resolve 函数:内部定义成功时调用的函数 resove(value)
- reject 函数:内部定义失败时调用的函数 reject(reason)
- 说明:executor 是执行器,会在 Promise 内部立即同步回调,异步操作 resolve/reject 就在 executor中
2. Promise.prototype.then 方法:p.then(onResolved, onRejected)
- onResolved 函数:成功的回调函数 (value) => {}
- onRejected 函数:失败的回调函数 (reason) => {}
- 说明:指定两个回调(成功+失败):用于得到成功 value 的成功回调和用于得到失败 reason 的失败回调,返回一个新的promise 对象
3. Promise.prototype.catch方法: (onRejected) => {}
- onRejected函数: 失败的回调函数(reason) => {}
- 说明: then()的语法糖, 相当于: then(undefined, onRejected)
new Promise((resolve, reject) => { // excutor执行器函数
setTimeout(() => {
if(...) {
resolve('成功的数据') // resolve()函数
} else {
reject('失败的数据') //reject()函数
}
}, 1000)
}).then(
value => { // onResolved()函数
console.log(value) // 成功的数据
}).catch(
reason => { // onRejected()函数
console.log(reason) // 失败的数据
}
)
4. Promise.resolve方法: (value) => {}
value: 成功的数据或promise对象说明: 返回一个成功/失败的promise对象
<script>
//如果传入的参数为 非Promise类型的对象, 则返回的结果为成功promise对象
let p1 = Promise.resolve(521);
console.log(p1);
//如果传入的参数为 Promise 对象, 则参数的结果决定了 resolve 的结果
let p2 = Promise.resolve(new Promise((resolve, reject) => {
// resolve('OK');//成功
reject('Error');//失败
}));
console.log(p2);
p2.catch(reason => {//失败时的处理
console.log(reason);
})
</script>
5.Promise.reject方法: (reason) => {}
reason: 失败的原因说明: 返回一个失败的promise对象
<script>
// let p = Promise.reject(521);
// let p2 = Promise.reject('iloveyou');
let p3 = Promise.reject(new Promise((resolve, reject) => {
resolve('OK');
}));
console.log(p3);
</script>
Promise.resolve()/Promise.reject() 方法就是一个语法糖,用来快速得到Promise对象。
//产生一个成功值为1的promise对象
new Promise((resolve, reject) => {
resolve(1)
})
//相当于
const p1 = Promise.resolve(1)
const p2 = Promise.resolve(2)
const p3 = Promise.reject(3)
p1.then(value => {console.log(value)}) // 1
p2.then(value => {console.log(value)}) // 2
p3.catch(reason => {console.log(reason)}) // 3
6.Promise.all方法: (promises) => {}
promises: 包含n个promise的数组说明: 返回一个新的promise, 只有所有promise都成功才成功,结果是成功的结果组成的数组;只要有一个失败了就直接失败,结果是失败那个对象的结果。
let p1 = new Promise((resolve, reject) => {
resolve('OK');
})
let p2 = Promise.resolve('Success');
let p3 = Promise.resolve('Ohhhhh');
const result = Promise.all([p1, p2, p3]);
console.log(result);
7.Promise.race方法: (promises) => {}
promises: 包含n个promise的数组说明: 返回一个新的promise, 第一个完成的promise的结果状态就是最终的结果状态。
<script>
let p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('OK');
}, 1000);
})
let p2 = Promise.resolve('Success');
let p3 = Promise.resolve('Oh Yeah');
//调用
const result = Promise.race([p1, p2, p3]);
console.log(result);
</script>