一.用promise对象处理异步
创建promise异步编程
resolve reject 回调函数
resolve 成功的时候回调函数
reject 失败的时候
Promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的回调函数(then括号里边写回调函数)
//首先要生成promise实例
const promise = new Promise(function (resolve, reject) {
if (true) { //异步操作成功
resolve("数据"); //resolve,reject是两个函数
}
else {
reject("失败");
}
})
//在外边获取异步数据
promise.then(function (res) {
console.log(res);
}), function (error) {
console.log(error);
}
下边这种写法比较高级,只写了成功时候的的程序
function timeout(ms) {
return new Promise((resolve, reject) => {
setTimeout(resolve, ms, 'done');
});
}
timeout(100).then((value) => {
console.log(value);
});
settimeout的第三个参数
前面的回调函数的附加参数
function show(){
return setTimeout((a,b,c) => {
console.log(a,b,c)
}, 1000, "my", "name", "is starsion");
}
show(); //输出
my name is starsion
一个promise 只能写一个请求
promise与抓异常语句一起使用
catch里边的参数,是new Error里边定义的异常信息
promise.then().catch()
catch里边抛出异常信息
let promise=new Promise(function (resolve,reject){
try{
if(true){
setTimeout(resolve,100,1);
}
else{
throw new Error("数据请求异常!");
}
}
catch(err){
reject(err);
}
});
promise.then(function (res){
console.log(res);
}).catch(function (err){
console.log(err);
});
promise对象的执行顺序
var data=null;
var promise=new Promise(function(resolve){
console.log("start");
setTimeout(resolve,1000,"内部");
});
console.log("外部");
promise.then(function(res){
console.log(res);
data=123;
});
console.log("end");
console.log(data); //null
“内部”会隔一秒再输出,data输出的是null(内部还没有执行完,data还没有赋上值,代码的异步执行)
二.promise 异步加载图片
浏览器性能优化
var promise=new Promise(function(resolve,reject){
var imges=new Image();
imges.src="img/01.jpg";
imges.onload=function(res){
setTimeout(resolve,1000,imges);
};
imges.error=function(){
reject(new Error("图片异常!"))
}
});
promise.then(function(res){
console.log(res); //<img src="img/01.jpg">
}),function(err){
console.log(err);
}
三.用promise对象实现AJAX操作
原生ajax的promise异步封装
onreadystatechange 读取事件的状态 里边判断readyState=4,status=200
responseType 数据类型
const post = function (url, data) {
const promise = new Promise(function (resolve, reject) {
let http = new XMLHttpRequest();
let handle = function () {
if (http.readyState != 4) {
return;
}
if (http.status == 200) {
resolve(http.response);
}
else {
reject(new Error("请求数据失败!"));
}
}
http.open("post", url);
http.onreadystatechange = handle;
http.responseType = "json";
if (data) {
http.send(data);
}
else {
http.send();
}
});
return promise;
}
//post里边是要传的数据
post("./data/stu.json").then(function (res){
console.log(res);
}).catch(function(err){
console.log(err);
});
es6教程
const getJSON = function(url) {
const promise = new Promise(function(resolve, reject){
const handler = function() {
if (this.readyState !== 4) {
return;
}
if (this.status === 200) {
resolve(this.response);
} else {
reject(new Error(this.statusText));
}
};
const client = new XMLHttpRequest();
client.open("GET", url);
client.onreadystatechange = handler;
client.responseType = "json";
client.setRequestHeader("Accept", "application/json");
client.send();
});
return promise;
};
getJSON("/posts.json").then(function(json) {
console.log('Contents: ' + json);
}, function(error) {
console.error('出错了', error);
});
四.多个promise连用
promise2等待promise1结束
①
var promise1=new Promise(function(resolve,reject){
setTimeout(resolve,5000,"数据");
})
var promise2=new Promise(function(resolve,reject){
setTimeout(resolve,1000,promise1);
})
promise2.then(function(res){
console.log(res);
})
②
const p1 = new Promise(function (resolve, reject) {
setTimeout(() => reject(new Error('fail')), 3000)
})
const p2 = new Promise(function (resolve, reject) {
setTimeout(() => resolve(p1), 1000)
})
p2.then(result => console.log(result))
.catch(error => console.log(error)) // Error: fail 因为p1是输出错误信息,所以是catch这一行输出
五.promise原型的then,catch,finally方法
① Promise.prototype.catch()
用于指定发生错误时的回调函数。
② Promise.prototype.finally()
finally方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。
finally:操作服务器之后,可以在异步编程里边进行关闭,也可以等待数据在promise里边拿完之后在finally里边进行关闭,因为finally最后一定会执行。
promise
.then(result => {···})
.catch(error => {···})
.finally(() => {···});
不管promise最后的状态,在执行完then或catch指定的回调函数以后,都会执行finally方法指定的回调函数。
例子:服务器使用 Promise 处理请求,然后使用finally方法关掉服务器。
server.listen(port)
.then(function () {
// ...
})
.finally(server.stop);
③ Promise.prototype.then()
Promise 实例具有then方法,也就是说,then方法是定义在原型对象Promise.prototype上的。它的作用是为 Promise 实例添加状态改变时的回调函数。then方法的第一个参数是resolved状态的回调函数,第二个参数(可选)是rejected状态的回调函数。
then方法返回的是一个新的Promise实例(注意,不是原来那个Promise实例)。因此可以采用链式写法,即then方法后面再调用另一个then方法。
④ constructor
构造函数就是new Promise()括号里边的回调函数
⑤ Promise.all()
Promise.all( )方法用于将多个 Promise 实例,包装成一个新的 Promise 实例
链式操作then方法里边必须写return,不然all里边拿不到
连着点的时候需要return
const p1=new Promise(function(resolve,reject){
setTimeout(resolve,2000,"学生");
})//.then(res=>res).catch(err=>err); 注释掉的也可以不写,最后也可以输出值
const p2=new Promise(function(resolve,reject){
setTimeout(resolve,4000,"老师");
})//.then(res=>res).catch(err=>err);
const p3=Promise.all([p1,p2]).then(res=>console.log(res)).catch(err=>console.log(err));
p3 p4 是一个新的promise 若什么都不写便没有promiseValue值,里边要写return 返回res
const p1 = new Promise(function (resolve, reject) {
setTimeout(resolve, 1000, "学生");
});
// p3 p4 是一个新的promise 没有promiseValue
let p3=p1.then(function (res){
return res; //若这里边没有这个return的话,promiseValue的值为undefined,想有value值,里边必须写return值
});
const p2 = new Promise(function (resolve, reject) {
setTimeout(resolve, 1000, "老师");
});
let p4=p2.then(function (res){
return res;
});
console.log(p3,p4);
//合并
const p5 = Promise.all([p1, p2]).then(function (res) {
console.log(res);
}).catch(function (err) {
console.log(err);
});
若第一个then不给第二个then 返回res,则第二个then新new的promise会没有参数,输出的会是undefined;
const p = new Promise(function (resolve, reject) {
setTimeout(resolve, 1000, "数据");
}).then(function (res) {
console.log(res); //数据
return res;
}).then(function (res) {
console.log(res); //若没有上一个return,输出为undefined;上一个return了之后输出的是数据
//第一个then出了一个新的promise,可是这个promise的promiseValue的值为空,必须return res给这个promiseValue赋值,下一个then才可以接收到值
return res;
}).then(function (res) {
console.log(res);
});
es6官方文档里边的案例
const p1 = new Promise((resolve, reject) => {
resolve('hello');
}).then(result => result)
.catch(e => e);
const p2 = new Promise((resolve, reject) => {
throw new Error('报错了');
}).then(result => result)
.catch(e => console.log(e));/*throw new出的错误,会在catch中报出*/
Promise.all([p1, p2])
.then(result => console.log(result))
.catch(e => console.log(e));
// ["hello", Error: 报错了]