1、什么是Promise?
- 主要用于异步计算
- 可以将异步操作队列化,按照期望的顺序执行,返回符合预期的结果
- 可以在对象之间传递和操作promise,帮助我们处理队列
2、Promise的好处
- promise是一个对象,对象和函数的区别就是对象可以保存状态,函数不可以(闭包除外)
- 可以很好的解决回调深渊的问题
- 语法简洁。可读性强
- 多个异步等待合并便于解决
3、用法
- resolve:将Promise对象的状态从“未完成”变为“成功”(即从 pending 变为 fulfilled)。将异步的执行从pending(请求)变成了resolve(成功返回),是个函数执行返回。
- reject:将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected)。顾名思义“拒绝”,就是从请求变成了"失败",是个函数可以执行返回一个结果,但我们这里推荐大家返回一个错误new Error(),也可直接返回字符串。
- Promise构造的实例存在then()、catch()、finally()方法
- Promise的状态改变,只有两种可能:从pending变为fulfilled;从pending变为rejected。
const function1 = new Promise((resolve, reject) => {
// resolve('what do you do?')
reject(new Error('find problem?'))
})
function1
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})
4、使用
(1)如果有两个异步操作(执行需要时间),吃饭和收碗分别为function1()和function2(),setTimeout()模拟其所需要的时间,要求两个异步操作按顺序执行,先执行function1()再执行function2()
const fun1 = () => {
// 模拟接口返回时间
setTimeout(() => {
console.log('吃饭')
}, 200)
}
const fun2 = () => {
setTimeout(() => {
console.log('收碗')
},100)
}
fun1()
fun2()
// 执行结果:
//收碗
//吃饭
这样写的活,两个函数的执行是同步的,同时进行,很明显不是我们想要的结果
const fun1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('吃饭')
// reject(new Error('find problem?'))
}, 200)
})
const fun2 = () => {
setTimeout(() => {
console.log('收碗')
},100)
}
fun1
.then(res => {
console.log(res)
fun2()
})
.catch(err => {
console.log(err)
})
// 执行结果:
//吃饭
//收碗
fun1()用Promise构造实例,并用resolve返回,then()方法接收resolve传递的数据。这样等fun1()执行完再执行fun2()。
(2)解决地狱回调,将函数嵌套的代码方式改为平级的,支持链式调用
const fun1 = f => {
console.log('f1')
f()
}
const fun2 = f => {
console.log('f2')
f()
}
const fun3 = f => {
console.log('f3')
f()
}
const fun4 = f => {
console.log('f4')
f()
}
fun1(() => {
fun2(() => {
fun3(() => {
fun4(() => {})
})
})
})
//输出结果
//f1
//f2
//f3
//f4
函数嵌套,一层套一层,地狱回调
const fun1 = () => {
return new Promise((resolve, reject) => {
resolve('f1')
})
}
const fun2 = () => {
return new Promise((resolve, reject) => {
resolve('f2')
})
}
const fun3 = () => {
return new Promise((resolve, reject) => {
resolve('f3')
})
}
const fun4 = () => {
return new Promise((resolve, reject) => {
resolve('f4')
})
}
fun1()
.then(res => {
console.log(res)
return fun2()
})
.then(res => {
console.log(res)
return fun3()
})
.then(res => {
console.log(res)
return fun4()
})
.then(res => {
console.log(res)
})
使用Promise()可以改成平级,解决地狱回调。也可以通过async+await解决
5、all()和race()的用法
- Promise.all()方法提供了并行执行异步操作的能力,并且在所有异步操作执行完后才执行then()回调,一个失败则执行catch()。
const fun1 = new Promise((resolve, reject) => {
resolve('f1')
})
const fun2 = new Promise((resolve, reject) => {
resolve('f2')
// reject('f2 error')
})
const fun3 = new Promise((resolve, reject) => {
resolve('f3')
})
const fun = () => {
return Promise.all([fun1, fun2, fun3])
}
fun()
.then(res => {
const [fun1, fun2, fun3] = res
console.log(fun1, fun2, fun3)
})
.catch(err => {
console.log(err)
})
// 输出结果:
//f1,f2,f3
//若fun2改为reject('f2 error')
//则结果:
//f2 error
- Promise.race(),哪个结果获得的快,就返回那个结果,不管结果本身是成功状态还是失败状态
const fun1 = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('f1')
}, 300)
})
}
const fun2 = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
// resolve('f2')
reject('f2 error')
})
}, 100)
}
const fun3 = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('f3')
}, 200)
})
}
const fun = () => {
return Promise.race([fun1(), fun2(), fun3()])
}
fun()
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})
//输出结果:
//f2 error
6、resolve() 和 reject() 可以直接被调用
- Promise.resolve() 和 Promise.reject() 可以直接被调用。有时候,当判断出 promise 并不需要真正执行时,我们并不需要 使用 new 创建 Promise 对象,而是可以直接调用 Promise.resolve() 和 Promise.reject()。
const fun1 = () => {
return Promise.resolve('f1')
}
const fun2 = () => {
return Promise.reject('f2 error')
}
fun1().then(res => {
console.log(res)
})
fun2().catch(err => {
console.log(err)
})
//输出结果
//f1
//f2 error