0.引子
1.什么是promise?
promise是ES6中新增的异步编程解决方案
, 在代码中的表现是一个对象
2.promise作用
- 企业开发中为了保存
异步代码的执行顺序
, 那么就会出现回调函数层层嵌套
- 如果回调函数嵌套的层数太多, 就会导致代码的阅读性, 可维护性大大降低
- promise对象可以将异步操作以同步流程来表示, 避免了回调函数层层嵌套(回调地狱)
例如:
需求: 从网络上加载3个资源, 要求加载完资源1才能加载资源2, 加载完资源2才能加载资源3,前面任何一个资源加载失败, 后续资源都不加载
function request(fn) {
setTimeout(function () {
fn("拿到的数据");
}, 1000);
}
request(function (data) {
console.log(data, 1);
request(function (data) {
console.log(data, 2);
request(function (data) {
console.log(data, 3);
});
});
});
// 回调函数层层嵌套
使用promise
function request() {
return new Promise(function (resolve, reject) {
setTimeout(function () {
resolve("拿到的数据");
}, 1000);
});
}
request().then(function (data) {
console.log(data, 1);
return request();
}).then(function (data) {
console.log(data, 2);
return request();
}).then(function (data) {
console.log(data, 3);
});
一、基础概念
1.什么是Promise?
Promise是ES6中新增的一个对象,
通过Promise就可以实现 用同步的流程来表示异步的操作
通过Promise就可以 避免回调函数层层嵌套(回调地狱
)问题
2.如何创建Promise对象?
new Promise(function(resolve, reject){});
promise对象不是异步的, 只要创建promise对象就会立即执行存放的代码
3.Promise是如何实现 通过同步的流程来表示异步的操作的?
promise对象是通过状态的改变来实现的, 只要状态发生改变就会自动触发对应的函数
4.Promise对象三种状态
pending
: 默认状态,只要没有告诉promise任务是成功还是失败就是pending状态fulfilled(resolved)
: 只要调用resolve函数, 状态就会变为fulfilled, 表示操作成功rejected
: 只要调用rejected函数, 状态就会变为rejected, 表示操作失败- 注意点:
状态一旦改变既不可逆
, 既从pending变为fulfilled, 那么永远都是fulfilled,既从pending变为rejected, 那么永远都是rejected
5.监听Promise状态改变
我们还可以通过函数来监听状态的变化
- resolved --> then()
- rejected --> catch()
二、promise-then方法
1.then方法接收两个参数
- 第一个参数是
状态切换为成功时
的回调 - 第二个参数是
状态切换为失败时
的回调
let promise = new Promise((resolve, reject)=>{
// resolve() // 将状态修改为成功,执行成功时的回调
reject() // 将状态修改为失败,执行失败时的回调
})
promise.then(function(){
console.log('成功时的回调');
},function(){
console.log('失败时的回调');
})
2.在修改promise状态时,可以传递参数给then方法中成功的回调
let promise = new Promise((resolve, reject)=>{
// resolve() // 将状态修改为成功,执行成功时的回调
reject('123') // 将状态修改为失败,执行失败时的回调
})
promise.then(function(){
console.log('成功时的回调');
},function(res){
console.log('失败时的回调', res);
})
=========>
function success(){
console.log('success123');
}
function error(data){
console.log('error',data);
}
let promise = new Promise((resolve, reject)=>{
// resolve() // 将状态修改为成功,执行成功时的回调
reject('123') // 将状态修改为失败,执行失败时的回调
})
promise.then(success, error)
3.同一个promise对象可以多次调用then方法,当该promise对象的状态时所有
then方法都会被执行
let promise = new Promise((resolve, reject)=>{
// resolve() // 将状态修改为成功,执行成功时的回调
reject('123') // 将状态修改为失败,执行失败时的回调
})
promise.then(function(){
console.log('成功时的回调1');
},function(res){
console.log('失败时的回调1', res);
})
promise.then(function(){
console.log('成功时的回调2');
},function(res){
console.log('失败时的回调2', res);
})
4. then方法每次执行完毕后会返回一个新的promise对象
let promise = new Promise((resolve, reject)=>{
// resolve() // 将状态修改为成功,执行成功时的回调
reject('123') // 将状态修改为失败,执行失败时的回调
})
let p2 = promise.then(function(){
console.log('成功时的回调1');
},function(res){
console.log('失败时的回调1', res);
})
console.log(p2); // promise对象
console.log(p2 === promise); // false
5.可以通过上一个promise对象的then方法给下一个promise对象的then方法传递参数
注意点:
无论是在上一个promise对象成功的回调还是失败的回调传递的参数,
都会传递给下一个promise对象成功
的回调
let promise = new Promise((resolve, reject) => {
// resolve() // 将状态修改为成功,执行成功时的回调
reject('123') // 将状态修改为失败,执行失败时的回调
})
let p2 = promise.then(function (res) {
console.log('成功时的回调1', res);
return '123'
}, function (res) {
console.log('失败时的回调1', res);
return 'bbb'
})
p2.then(function (res) {
console.log('成功时的回调2', res);
}, function (res) {
console.log('失败时的回调2', res);
})
then方法返回的promise在promise.then可以接收到then方法return的参数
6.如果then方法返回的是一个Promise对象
, 那么会将返回的Promise对象的执行结果中的值
传递给下一个then方法
let promise = new Promise((resolve, reject)=>{
resolve('1')
})
let ppp = new Promise((resolve, reject)=>{
reject('ppp')
})
let p1 = promise.then(function(data){
console.log('成功1', data);
return ppp
},function(data){
console.log('失败1', data);
})
p1.then(function(data){
console.log('成功2', data);
},function(data){
console.log('失败2', data);
})
三、promise-catch方法
1.catch
其实是 then(undefined, () => {})
的语法糖,没有成功的回调,只有失败的回调
let promise = new Promise(function (resolve, reject) {
// resolve(); // 将状态修改为成功
reject(); // 将状态修改为失败
});
promise.catch(function () {
console.log("abc");
});
2.分开监听使用链式编程
如果需要分开监听, 也就是通过
then监听成功
通过catch监听失败
那么必须使用链式编程, 否则会报错
let promise = new Promise((resolve, reject)=>{
reject()
})
promise.then(function(){
console.log('成功1');
})
promise.catch(function(){
console.log('err');
}) // 能监听到失败,但是会报错
=修改=>
promise.then(function(){
console.log('成功1');
}).catch(function(){
console.log('err');
})
2.1 使用链式编程的原因是
- 1.如果promise的状态是
失败
, 但是没有对应失败的监听就会报错 - 2.then方法会返回一个
新的promise
, 新的promise会继承
原有promise的状态 - 3.如果新的promise状态是
失败
, 但是没有
对应失败的监听
也会报错
let promise = new Promise(function (resolve, reject) {
// resolve(); // 将状态修改为成功
reject(); // 将状态修改为失败
});
let p2 = promise.then(function () {
console.log("成功");
});
console.log(p2);
promise.catch(function () {
console.log("失败1");
});
// P2新的promise继承原有的promise状态,状态是失败,没有对应失败的监听会报错
p2.catch(function () {
console.log("失败2");
});
3.和then一样, 在修改promise状态时, 可以传递参数给catch方法中的回调函数
let promise = new Promise((resolve, reject)=>{
reject('失败了哦')
})
promise.catch(function(data){
console.log(data); // 失败了哦
})
4.和then一样, 同一个promise对象可以 多次 调用catch方法, 当改变promise对象的状态时所有catch方法都会被执行
let promise = new Promise((resolve, reject) => {
reject()
})
promise.catch(function () {
console.log('失败1');
})
promise.catch(function () {
console.log('失败2');
})
promise.catch(function () {
console.log('失败3');
})
/**
执行结果
失败1
失败2
失败3
*/
5.和then一样, catch方法每次执行完毕后
会返回一个 新的promise对象
let promise = new Promise((resolve, reject) => {
reject()
})
let p1 = promise.catch(function () {
console.log('失败1');
})
console.log(p1);
console.log(p1 === promise);
6.和then方法一样, 上一个promise对象
也可以 给 下一个promise 成功的
传递参数
注意点:
无论是在上一个promise对象成功的回调还是失败的回调
传递的参数,
都会传递给下一个promise对象成功的回调
let promise = new Promise(function (resolve, reject) {
reject();
});
let p2 = promise.catch(function () {
console.log("失败1");
return "it666";
});
p2.then(function (data) {
console.log("成功2", data);
}, function (data) {
console.log("失败2", data);
});
/*
执行结果:
失败1
成功2,it666
*/
7.和then一样, catch方法如果 返回的是一个 Promise对象
, 那么会将返回的Promise对象的执行结果
中的值传递给下一个 catch方法
let promise = new Promise(function (resolve, reject) {
reject();
});
let ppp = new Promise(function (resolve, reject) {
// resolve("1111");
reject("abcd");
});
let p2 = promise.catch(function () {
console.log("失败1");
return ppp;
});
p2.then(function (data) {
console.log("成功2", data);
}, function (data) {
console.log("失败2", data);
});
/*
执行结果:
失败1
失败2 abcd
*/
8.和then方法第二个参数的区别在于, catch方法可以捕获
上一个promise对象then方法中的异常
then方法中
let promise = new Promise(function (resolve, reject) {
resolve();
});
promise.then(function () {
console.log("成功");
xxx
}, function () {
console.log("失败");
});
catch方法中:
let promise = new Promise(function (resolve, reject) {
resolve();
});
promise.then(function () {
console.log("成功");
xxx
}).catch(function (e) {
console.log("失败", e);
});
学习笔记❥(^_-)