Promise主要用于解决异步回调问题。
在网络请求中如果不使用promise,有可能会遇到回调地狱问题,多层回调请求层层嵌套。
1.使用setTimeout来模拟网络请求
这实际上就是异步操作,下面的"黑"会先于"Hello World"打印"。
下面这样写,第三个请求需要等待第二个请求完成,第二个请求需要等待第一个请求完成。
setTimeout(() => {
console.log("Hello,World");
setTimeout(() => {
console.log("Hello,Vuejs")
setTimeout(() => {
console.log("Hello,python")
},1000)
},1000)
},1000)
console.log("黑")
2.网络请求配合上promise更好。
Promise是一个构造函数,所以要用new来创建。
// 参数 -> 函数(resolve,reject)
// resolve,reject本身也是函数
// 为什么promise可以链式调用,因为每个实例的then都是返回一个新的promise实例,而每个promise又都有then函数
// new Promise((resolve,reject) => {}).then().then()
new Promise((resolve,reject) => {
setTimeout(() => {
resolve()
},1000)
}).then(() => {
console.log("Hello,World");
return new Promise((resolve,reject) => {
setTimeout(() => {
resolve()
},1000)
}).then(() => {
console.log("Hello,Vuejs");
return new Promise((resolve,reject) => {
setTimeout(() => {
resolve()
},1000)
}).then(() => {
console.log("Hello,python")
})
})
})
3.什么情况会用到promise:一般情况下有异步操作时,使用promise对异步操作进行封装。
new Promise((resolve,reject) => {
setTimeout(() => {
// 成功的时候
resolve("hello") // 去then
// 失败的时候
reject("失败了") // 去catch
},1000)
}).then((data) => {
// 在这里处理代码
console.log(data);
}).catch((error) => {
console.log(error)
})
4.promise的状态
promise具有几种状态
输出的p将会返回一个Promise对象,包含了状态和结果
PromiseState: 三种状态(pending,准备,待解决,进行中)(fulfilled,已完成,成功)(rejected,已拒绝,失败)
PromiseState状态的改变是一次性的,如果resolve调用成功了以后,再去调用reject此时状态不会由fulfilled装为rejected。
Promise结果:PromiseResult
promise里面的状态不改变,不会执行then里面的方法
const p = new Promise((resolve,reject) => {
resolve("成功") // 使当前Promise对象的PromiseState由pending改变为fulfilled,PromiseResult的值为成功
reject("失败") // 使当前Promise对象的PromiseState由pending改变为rejected,PromiseResult的值为失败
})
console.log(p);
// then方法调用
// 通过打印Promise构造函数,可以发现promise的原型上挂载了很多方法,可以看到then方法是有两个参数的
// 两个参数都是函数,then的返回值是一个Promise对象
const t = p.then((value) => {
// 当Promise的状态是fulfilled时调用
console.log("成功时调用",value)
}, (reason) => {
// 当Promise的状态是rejected时调用
console.log('失败时调用',reason)
})
console.log(t);
5.catch捕获错误
注意:目前使用的方法都是通过挂载在原型上的,所以才可以使用
catch实际上就相当于then方法中的第二个参数函数,不过一般都习惯于使用catch函数
const p = new Promise((reslove,reject) => {
// 以下三种方式都会触发catch()
reject()
console.log(a);
throw new Error("出错了")
})
思考catch中的参数函数在什么时候被执行?
1.当Promise的状态改为rejected的时候。
2.当Promise执行出错的时候也会执行。总而言之捕获错误
p.catch((reason) => {
console.log("失败了",reason);
})
console.log(p)
6.all方法
用于两个ajax请求并发执行,模拟
Promise.all([
new Promise((resolve,reject) => {
$ajax({
url: '',
success: function(data) {
resolve(data)
}
})
}),
new Promise((resolve,reject) => {
$ajax({
url: '',
success: function(data) {
resolve(data)
}
})
}),
]).then(results => { // 这里的results是一个数组,因为ajax请求就是数组
console.log(results[0]); // 第一次请求的
console.log(results[1]); // 第二次请求的
})