一、介绍
Promise
,译为承诺,是异步编程的一种解决方案,比传统的解决方案(回调函数)更加合理和更加强大,能够解决回调地狱的问题。
doSomething(function(result) {
doSomethingElse(result, function(newResult) {
doThirdThing(newResult, function(finalResult) {
console.log('得到最终结果: ' + finalResult);
}, failureCallback);
}, failureCallback);
}, failureCallback);//回调地狱
但我们通过promise初体验,写一个定时器,来展现他的好处如下:
<body>
<button class="btn-1" id="btn">惦记我</button>
<script>
function rand(m,n){
return Math.ceil(Math.random()*(n-m+1)) + m-1;
}//随机函数
var btn = document.querySelector('#btn');
btn.addEventListener('click',function(){
/* setTimeout(()=>{
var t = rand(1,100)
if(t<=30){
alert('zhongjiang')
}
else{
alert('no');
}
},1000) */
const p = new Promise((resolve,reject) =>{
setTimeout(()=>{
var t = rand(1,100)
if(t<=30){
//alert('zhongjiang')
resolve(t);
}
else{
//alert('no');
reject(t);
}
},1000);
});
p.then((value) =>{
alert('yes'+ value);
},(reason) =>{
alert('no' + reason);
});
});
</script>
</body>
瞬间感受到promise
解决异步操作的优点:
- 链式操作减低了编码难度
- 代码可读性明显增强
特点
- 对象的状态不受外界影响,只有异步操作的结果,可以决定当前是哪一种状态
- 一旦状态改变(从
pending
变为fulfilled
和从pending
变为rejected
),就不会再变,任何时候都可以得到这个结果
二、异步与promise模式
如何让一个回调的异步函数变成Promis的异步函数
- 第一步
return new Promise((resolve,reject)+>{....})
- 任务成功调用resolve(result)
- 任务失败调用reject(error)
- resolve和reject会再去调用成功和失败函数
- 第二步
- 使用.then(success,fail)传入成功和失败函数
- 补充:promise不可被取消
三、promise与Ajax
1. 介绍
AJAX,是 Asynchronous JavaScript And XML,意思是利用JavaScript执行异步网络请求,对页面进行局部更新,而不需要重载页面。
AJAX是浏览器的功能,利用浏览器在window上增加的XMLHttpRequest函数,利用该函数构造出一个对象,使用该对象进行请求发送与响应接受。
2. 使用
- 创建一个
XMLHttpRequest
对象 - 调用对象的
open
方法启用。 - 监听对象的
onreadystatechange
事件(或者是onload
和onerror
事件),处理函数对返回的数据进行处理。 - 调用对象的
send
方法发送请求
3. onreadystatechange
值 | 状态 | 描述 |
---|---|---|
0 | UNSENT | 代理被创建,但尚未调用 open() 方法。 |
1 | OPENED | open() 方法已经被调用。 |
2 | HEADERS_RECEIVED | send() 方法已经被调用,并且头部和状态已经可获得。 |
3 | LOADING | 下载中; responseText 属性已经包含部分数据。 |
4 | DONE | 下载操作已完成。 |
创建 -> 打开 -> 发送 -> 接收 -> 完成
每一次state的改变都会触发readystatechange事件,但我们一般只关心state为4的阶段,此阶段数据接收已完成,可来进行数据处理。onload函数也会在请求完成后即state为4的时候调用。
<body>
<div class="11" >
<button id="btn"> 点击</button>
</div>
<script>
const btn = document.querySelector('#btn');
/* btn.addEventListener('click',function(){
const xhr = new XMLHttpRequest();
xhr.open('GET','https://api.apiopen.top/getJok');
xhr.send();
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
if(xhr.status>=200 && xhr.status <300){
console.log(xhr.response);
}
else{
console.log(xhr.status);
}
}
}
}); */
btn.addEventListener('click',function(){
const p =new Promise((resolve,reject)=>{
const xhr = new XMLHttpRequest();
xhr.open('GET','https://api.apiopen.top/getJok');
xhr.send();
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
if(xhr.status>=200 && xhr.status <300){
//console.log(xhr.response);
resolve(xhr.response);
}
else{
//console.log(xhr.status);
reject(xhr.status);
}
}
}
});
p.then(value =>{
console.log(value)
},reson =>{
console.warn(reason)
})
});
</script>
</body>