PromiseES6引入的语法,专门处理异步编程
promise 基本用法
- 实例化Promise对象,构造函数中传递函数,该函数中用于处理异步任务
- resolve和reject两个参数用于处理成功和失败两种情况,并通过p.then获取处理结果
例如如下代码:
var p = new Promise(function (resolve,reject){
//这里开一个定时器模仿异步任务
setTimeout(function(){
var flag = turn;
if(flag) {
//正常情况下拿到数据
resolve('我是成功时的返回数据');
} else {
//服务器出错,响应的错误信息
reject('出错了');
}
},1000);
});
p.then(function(data) {
//在这里用data接收正确信息
console.log(data);
},function(info) {
//在这里用info接收错误数据
console.log(info);
});
Promise 处理原生Ajax
//基于Promise发送Ajax请求
function queryData(url) {
var p = new Promise(function(resolve,reject) {
var xhr = new XMLHttpRequest();
//每当 readyState 改变时,就会触发 onreadystatechange 事件
xhr.onreadystatechange =function() {
if(xhr.readyState != 4) return;
if(xhr.readyState === 4 && xhr.status ===200) {
resolve(xhr.responseText);//拿到响应数据(以文本形式)
} else {
reject('服务器错误');
}
};
xhr.open('get',url);
xhr.send(null);
});
return p;
}
queryData('http://localhost:3000/data')
.then(function(data) {
console.log(data);//打印正确的响应数据
},function(info) {
console.log(info)//打印错误信息
});
readyState状态码和HTTP状态码
onload
进入onload之后,只出现了状态码4。也就是说,只有处于状态码4,请求已完成,响应已就绪的情况下,才会进入onload。只要进入onload请求中,一定是已经到4这个状态了。
function loadText(){
let xhr = new XMLHttpRequest();
xhr.open('GET','sample.txt',true);
console.log("READYSTATE"+ xhr.readyState);
//两种请求方式onload和onreadystatechange
xhr.onload = function(){
console.log("READYSTATE"+ xhr.readyState);
console.log(this.responseText);
}
xhr.send();
}
onreadystatechange 事件
当请求被发送到服务器时,我们需要执行一些基于响应的任务。
每当 readyState 改变时,就会触发 onreadystatechange 事件。
readyState 属性存有 XMLHttpRequest 的状态信息。
以下是 XMLHttpRequest 对象的三个重要的属性:
在 onreadystatechange 事件中,我们规定当服务器响应已做好被处理的准备时所执行的任务。
当 readyState 等于 4 且状态为 200 时,表示响应已就绪:
//注意:onreadystatechange 事件被触发 5 次(0 - 4),对应着 readyState 的每个变化。
xhr.open("get","test1.php",true);
xhr.send(null);
xhr.onreadystatechange = function(){
// 回调函数
if(xhr.readyState == 4){
if(xhr.status == 200){
var data = xhr.responseText; // 获取响应数据(以文本形式)
console.log(data);
}
}
}
发送多次Ajax请求
//基于Promise发送Ajax请求
function queryData(url) {
var p = new Promise(function(resolve,reject) {
var xhr = new XMLHttpRequest();
//每当 readyState 改变时,就会触发 onreadystatechange 事件
xhr.onreadystatechange =function() {
if(xhr.readyState != 4) return;
if(xhr.readyState === 4 && xhr.status ===200) {
resolve(xhr.responseText);//拿到响应数据(以文本形式)
} else {
reject('服务器错误');
}
};
xhr.open('get',url);
xhr.send(null);
});
return p;
}
//在这里我们解决发送多个Ajax请求,并把保证其顺序,利用Promise的.then()方法
//在这里我们忽略请求错误的情况
queryData('http://localhost:3000/data')
.then(function(data){
console.log(data)
//在这里return的时一个新的Promise对象
return queryData('http://localhost:3000/data1')
})
//这里调用的是上面return的Promise对象并且函数中的data用于接受上一个异步任务的处理结果
.then(function(data){
console.log(data)
return queryData('http://localhost:3000/data2')
})
.then(function(data){
console.log(data)
})
then
我们来对Promise实例对象的then方法做个分析
then的参数中的函数返回值有两个
- 返回Promise实例对象
– 返回的该实例对象会调用下一个then - 返回普通值
–返回的普通值会直接传递给下一个then,通过then参数中函数的参数接受该值
–这里注意,当参数是普通值时,会默认创建一个新的Promise实例对象,保证then 的链式编程可以正常进行下去
promise中常用的API
var p = new Promise(function(resolve,reject)
1.实例方法
- p.then() 得到异步任务的正确结果
- p.catch() 获取异常信息
- p.finally()成功与否都会执行(可以做一些提示信息)
2.promise的对象方法
- promise.all() 并发处理多个异步任务,所有任务都执行完成才能得到结果
- promise.race() 并发处理多个异步任务,只要有一个任务完成就能得到结果
下面我们用代码来看看
//基于Promise发送Ajax请求
function queryData(url) {
var p = new Promise(function(resolve,reject) {
var xhr = new XMLHttpRequest();
//每当 readyState 改变时,就会触发 onreadystatechange 事件
xhr.onreadystatechange =function() {
if(xhr.readyState != 4) return;
if(xhr.readyState === 4 && xhr.status ===200) {
resolve(xhr.responseText);//拿到响应数据(以文本形式)
} else {
reject('服务器错误');
}
};
xhr.open('get',url);
xhr.send(null);
});
return p;
}
var p1 = queryData('http://localhost:3000/a1');
var p2 = queryData('http://localhost:3000/a1');
var p3 = queryData('http://localhost:3000/a1');
//promise.all 在拿到三个返回数据后打印三个值
Promise.all([p1,p2,p3]).then(function(result){
console.log(result)
})
//promise.race 在拿到第一个返回数据就只输出它的值
Promise.race([p1,p2,p3]).then(function(result){
console.log(result)
})