什么是Promise
Promise 是异步编程的一种解决方案: 从语法上讲,promise是一个对象,从它可以获取异步操作的消息;从本意上讲,它是承诺,承诺它过一段时间会给你一个结果。 promise有三种状态:pending(等待态),fulfiled(成功态),rejected(失败态) ;状态一旦改变,就不会再变。创造promise实例后,它会立即执行。
Promise的作用
promise是用来解决两个问题的:
- 回调地狱,代码难以维护, 常常第一个的函数的输出是第二个函数的输入这种现象
- promise可以支持多个并发的请求,获取并发请求中的数据
之前写回调的形式
function fn(a,fn2){
if(a > 1){
fn2()
}
}
fn(2,function(){
console.log("你好")
})
let p = new Promise(((resolve, reject) => {
//执行一些异步操作
setTimeout(() => {
console.log("我执行了")
resolve("我是成功的")
},3000)
}))
p.then( (res)=> {
console.log(res)
},(err) => {
console.log(err)
})
Promise的构造函数接收一个参数:function(resolve,reject),并且这个函数需要传入两个参数:
- resolve :异步操作执行成功后的回调函数
- reject:异步操作执行失败后的回调函数 then中传了两个参数,then方法可以接受两个参数,第一个对应resolve的回调,第二个对应reject的回调
catch的效果和then的第二个函数效果一样,但是在执行resolve的回调(也就是上面then中的第一个参数)时,如果抛出异常了(代码出错了),那么并不会报错卡死js,而是会进到这个catch方法中。其作用与try-catch一致。
此处写一段链式调用的代码
注意如何在then中返回一个新的Promise,以及两种语法糖的使用
-
Promise.reslove()
-
return ...
-
return new Promise()
let p = new Promise(((resolve, reject) => {
//执行一些异步操作
setTimeout(() => {
var a = 3
resolve(a)
// reject(b)
},3000)
}))
p.then((data) => {
console.log(data);
return new Promise((resolve,reject) => {
var s = "此处执行了数据请求工作,成功"
resolve(s)
})
})
.then((data) => {
console.log(data);
return Promise.reject("抛出错误")
})
.then((data) => {
console.log(data);
},(err) => {
console.log(err)
return 1111
})
.then((data) => {
console.log(data);
})
Promise.all
promise.all 的特点:
- 入参是个由多个
Promise实例组成的数组 - 返回值是个
promise,因为可以使用.then - 如果全部成功,状态变为
resolved, 并且返回值组成一个数组传给回调 - 但凡有一个失败,状态变为
rejected, 并将error返回给回调
function myPromiseAll(p){
return new Promise((resolve,reject) => {
//执行判断
if(!Array.isArray(p)){
throw new TypeError("promises must be an array")
}
let result = [];
let count = 0;
//对p中的Promise对象进行判断
p.forEach((promise,index) => {
promise.then((res) => {
//此处不能用result.push(res),而是通过索引来添加,因为forEach是异步任务,如果用push可能会使得res的顺序错误。Promise.all返回的顺序不会改变。
result[index] = res
count++
//执行判断,当p中的promise对象都执行完成后,将result resolve出去
count === p.length && resolve(result)
},(err) => {
reject(err)
})
})
})
}
//测试
let p1 = Promise.resolve(1),
p2 = Promise.resolve(2),
p3 = Promise.resolve(3);
myPromiseAll([p1, p2, p3]).then((res)=>{
console.log(res, 'res')
}, (err)=>{
console.log(err, 'err')
})
//[ 1, 2, 3 ] res
实现Promise.race
function myPromiseRace(p){
return new Promise((resolve,reject) => {
p.forEach((promise,index) => {
Promise.resolve(promise).then((value) => {
resolve(value)
},(reason) => {
reject(reason)
})
})
})
}
let p1 = new Promise(((resolve, reject) => {
setTimeout(() => {
var a = 1
resolve(a)
},1000)
}))
let p2 = new Promise(((resolve, reject) => {
setTimeout(() => {
var b = 2
resolve(b)
})
}))
let p3 = new Promise(((resolve, reject) => {
reject(3)
}))
let p = [p1,p2,p3]
myPromiseRace(p).then((res)=> {
console.log(res)
},(err) => {
console.log(err)
})
完成forEach里面是异步任务,所以才能用来实现Promise.race