Promise快速上手
2020-10-10 本文已影响0人
小妹呀
概述
回调函数是JavaScript
异步编程的根基,但如果我们直接使用传统回调方式去完成复杂的异步流程,就无法避免回调函数嵌套的问题,即常说的“回调地狱”。
为了解决这个问题,CommonJS
社区提出了Promise
规范,在ES2015
中被标准化,成为语言规范。
Promise
就是一个对象,用来表示一个异步任务在最终结束后,是成功还是失败。类似于内部对外界做出了一个“承诺”,一开始,处于待定状态(Pending
),最终有可能是成功(Fulfilled
)状态,也有可能是失败(Rejected
)状态,最终的结果状态明确后,都会有相应的任务被执行,一但结果明确,就不可能再发生改变。
快速上手
const promise = new Promise(function (resolve, reject) {
// 这里用于兑现承诺
// 这里的代码会被同步执行,属于同步任务
console.log(1)
resolve(100) // 承诺达成
//reject(new Error('promise rejected')) // 承诺失败
})
// then 方法接收两个参数,第一个是成功回调,第二个是失败回调
promise.then(function(value) {
// promise的回调属于微任务
console.log('resolved', value)
}, function (error) {
console.log('rejected', error)
})
如果在回调函数中又需要发起一次异步任务,循环往复,依然会出现“回调地狱”,这是使用Promise
的一个常见误区,对于这种情况,我们应该借助于Promise then
方法链式调用的特点,保证异步任务的扁平化。
链式调用
-
then
方法内部会返回一个全新的Promise
对象 - 后面的
then
方法就是在为上一个then
返回的Promise
注册回调 - 前面
then
方法中回调函数的返回值会作为后面then
方法回调的参数 - 如果回调中返回的是
Promise
,那后面then
方法的回调会等待它的结束 - 使用
catch
捕获异常可以捕获到Promise
链条上的异常,但上一个示例中的第二个参数捕获异常函数只是给第一个Promise
注册了失败回调
const promise = new Promise(function (resolve, reject) {
resolve(100)
})
promise.then(function(value) {
console.log('resolved', value)
}).then(function (value){
console.log(value) // undefined
throw new Error()
}).catch(function (error) {
// catch 方法捕获异常
console.log('error') // 'error'
})
静态方法
resolve
- 该方法的作用是,快速的把一个值转换成一个
Promise
对象,例如Promise.resolve('foo')
Promise.resolve('foo').then(value => { console.log(value) // 'foo' })
- 如果resolve的参数是一个promise,则会原样返回这个promise
let promise = new Promise((resolve, reject) => {}) let promise2 = Promise.resolve(promise) console.log(promise === promise2) // true
reject
- 与
resolve
类似,会快速创建一个状态为失败的Promise
对象
all
- 参数为一个数组,当内部所有
Promise
都执行完毕后,返回的Promise
状态才会改变,若有一个Promise
状态为失败,则返回的Promise
对象状态也会变成失败,不再等待其它的Promise
let p1 = new Promise((resolve, reject) => {
resolve('p1')
})
let p2 = new Promise((resolve, reject) => {
setTimeout(function () {
resolve('p2')
}, 1000)
})
let p3 = new Promise((resolve, reject) => {
resolve('p3')
})
Promise.all([p1, p2, p3]).then(res => {
// 返回的结果与参数Promise对应
console.log(res) // ["p1", "p2", "p3"]
}).catch(error => {
console.log(error)
})
race
all
方法是等待所有任务结束,而race
只会等待第一个结束的任务