前言
在Javascript学习中,理解异步编程是非常重要,是Promise是Javascript异步编程的一种解决方案,想要解决异步、回调地狱等问题,必须要使用promise,本文章作为作者学习promise时的总结,希望能帮助大家。
Promise状态
Promise有三种状态,Pending(等待中),、Resolved(已解决/已完成)、Rejected(已拒绝/已失败)。
Promise只能通过由等待–>成功,或者等待—>失败,且状态不可逆转
如果成功执行resolve回调函数,失败执行reject函数;无论是等待、已成功或者已失败,都应给予相应的结果;
回调函数
回调地狱的概念:回调函数里面嵌套回调函数。
function add(a, b, callback) {
setTimeout(() => {
var sum = a + b
setTimeout(() => {
callback(sum)
})
})
}
function print(sum) {
console.log(sum) //3
}
add(1, 2, print)
通过promise可以让add函数的代码成层级更加清晰
function add(a, b, callback) {
new Promise((resolve, reject) => {
var sum = a + b
return new Promise((resolve, reject) => {
callback(sum)
})
})
}
function print(sum) {
console.log(sum) //3
}
add(1, 2, print)
**注意:**创建一个Promise对象会立即执行里面的代码,所以为了更好的控制代码的运行时刻,可以将其包含在一个函数中,并将这个Promise作为函数的返回值。
基本用法
Promise接受一个函数作为参数,该函数有两个参数,分别为resolve和reject。其中resolve函数是把Promise从等待状态转为成功状态,调用resolve函数将函数结果传递出去;reject函数是转为失败状态,调用reject把执行错误传递出去;
function add(a, b) {
const promise = new Promise((resolve, reject) => {
const num = a + b
resolve(num)
})
return promise
}
add(1, 2).then(res => {
console.log(res) //3
})
该add函数返回一个Promise并且把a + b的结果通过resolve()函数传递出去,在调用函数的时候通过then方法接收传递出来的参数;
Promise中的then方法
- then方法返回的也是一个Promise对象(无论函数内部返回什么类型的数据,函数都会进行加工返回一个Promise对象)
function add(a, b) {
const promise = new Promise((resolve, reject) => {
const num = a + b
resolve(num)
})
return promise
}
console.log(add(1, 2).then()) //Promise
控制台打印:
- then()函数内部返回为普通值(非Promise类型的属性),返回的普通值会直接传递给下一个then,通过then参数中函数的参数接收该值。
function add(a, b) {
const promise = new Promise((resolve, reject) => {
const num = a + b
resolve(num)
})
return promise
}
add(1, 2).then((res) => {
console.log(res) //3
return res * 100
}).then(res => {
console.log(res) //300
})
- 通过第一个参数捕获成功状态返回的参数(该函数通过.then方法专递一个res参数,通过res返回a + b的返回值)
function add(a, b) {
const promise = new Promise((resolve, reject) => {
const num = a + b
resolve(num) //3
})
return promise
}
add(1, 2).then((res) => {
console.log(res)
})
- 通过第二个参数捕获失败状态的参数
function add(a, b) {
const promise = new Promise((resolve, reject) => {
const num = a + b
reject('出错了')
})
return promise
}
add(1, 2).then((res) => {
console.log(res)
}, (err) => {
console.log(err) //出错了
});
- 也可以通过 throw 直接抛出以一个错误进行捕获
function add(a, b) {
const promise = new Promise((resolve, reject) => {
const num = a + b
throw Error('出错了')
})
return promise
}
add(1, 2).then((res) => {
console.log(res)
}, (err) => {
console.log(err) //Error:出错了
});
Promise中的catch函数
cath函数相当于then方法的第二个参数,指向reject的回调函数,还有一个作用是在执行resolve回调函数时,如果出现错误,抛出异常,不会停止运行,而是进入catch方法中。
function add(a, b) {
const promise = new Promise((resolve, reject) => {
const num = a + b
throw Error('出错了')
})
return promise
}
add(1, 2)
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err) //Error: 出错了
return 5
})
.then(res => {
// 继续执行
console.log(res) // 5
})
Promise中的finally函数
finally()方法用于指定不管 Promise 对象最后状态是Resolved还是Rejected,都会执行的操作,Pendding状态不会执行。
function add(a, b) {
const promise = new Promise((resolve, reject) => {
const num = a + b
throw Error('出错了')
})
return promise
}
add(1, 2)
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err) //Error: 出错了
})
.finally(() => {
console.log('我会被执行') // 我会被执行
})
Promise中的all函数
all()方法可以完成并行任务,方法接收一个数组,数组中的每一项都为一个Promise对象,当数组中的每一项都转为Resolved的时候,all方法的状态才转为Resolved,如果有一个对象的状态为Rejected,那么整个all函数的状态就转为Rejected;
注意: 如果all方法状态为resolve,该方法返回的结果为一个数组,返回数组结果每一项的顺序仅与promise的存放顺序相关,与每一项promise中的执行快慢无关;
let promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(1)
}, 2000)
})
let promise2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(2)
}, 1000)
})
Promise.all([promise1, promise2]).then(res => {
console.log(res)// [1, 2]
})
Promise中的race函数
reace函数接受的参数也是一个Promise数组,当最先执行完事件后,就直接返回该Promise对象的值,如果该对象状态为Resolved,那么自身就转为Resolved, 反正该对象状态为Rejected,那么自身就转为Rejected;
setTimeout(() => {
resolve(1)
}, 2000)
})
let promise2 = new Promise((resolve, reject) => {
setTimeout(() => {
reject(2)
}, 1000)
})
Promise.race([promise1, promise2]).then(res => {
console.log(res)
}, (err) => {
console.log(err) //2
})