在JavaScript中,所有代码都是单线程的,也就是同步执行的,而Promise为异步编程提供了一种解决方案。
什么时候会处理异步事件呢?
- 一种很常见的场景应该就是网络请求了。
- 我们封装一个网路请求的函数,因为不能立即拿到结果,所以不能像简单的1+2=7一样将结果返回。
- 所以往往我们会传入另一个函数,在数据请求成功时,将数据通过传入的函数回调出去。
- 如果只是一个简单的网络请求,那么这种方案不会给我们带来很大的麻烦。
- 但是当网络请求非常复杂的时候,就会出现回调地狱。
回调地狱
异步JavaScript或使用回调的JavaScript很难直观地得到正确的结果。出现回调地狱的最主要原因就是自己在编写代码的过程中过于刻板,循规蹈矩,以至于不断在一层函数下接着进行第二层,已达到第二层代码的执行效果。但很明显效果事半功倍。
//回调地狱
const p = new Promise((resolve, reject) => {
//模拟异步
setTimeout(() => {
console.log('第一次请求')
console.log('第一次请求')
console.log('第一次请求')
console.log('第一次请求')
console.log('第一次请求')/
setTimeout(() => {
console.log('第二次请求')
console.log('第二次请求')
console.log('第二次请求')
console.log('第二次请求')
console.log('第二次请求')
setTimeout(() => {
console.log('第三次请求')
console.log('第三次请求')
console.log('第三次请求')
console.log('第三次请求')
console.log('第三次请求')
})
})
},1000)
})
Promise状态
Promise异步操作有三个状态: pending(进行中)、fulfill(已成功)和rejected(已失败)。除了异步操作的结果,任何其他操作都无法改变这个状态。
Promise对象只有: 从pending变为fulfilled和从pending变为rejected的状态改变。只要处于fulfilled和rejected,状态就不会再变了,即resolved(已成型)。
Promise的基本使用
普通调用
const a = new Promise((resolve, reject) => {
//模拟异步
setTimeout(() => {
resolve()
}, 1000)
})
const b = new Promise((resolve, reject) => {
//模拟异步
setTimeout(() => {
resolve()
}, 1000)
})
const c = new Promise((resolve, reject) => {
//模拟异步
setTimeout(() => {
resolve()
}, 1000)
})
a.then(() => {
console.log('第一次请求')
console.log('第一次请求')
console.log('第一次请求')
console.log('第一次请求')
console.log('第一次请求')
})
b.then(() => {
console.log('第二次请求')
console.log('第二次请求')
console.log('第二次请求')
console.log('第二次请求')
console.log('第二次请求')
})
c.then(() => {
console.log('第三次请求')
console.log('第三次请求')
console.log('第三次请求')
console.log('第三次请求')
console.log('第三次请求')
})
多个回调
const p = new Promise((resolve, reject) => {
//模拟异步
setTimeout(() => {
resolve()
}, 1000)
}).then(() => {
console.log('第一次请求')
console.log('第一次请求')
console.log('第一次请求')
console.log('第一次请求')
console.log('第一次请求')
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve()
}, 1000)
})
}).then(() => {
console.log('第二次请求')
console.log('第二次请求')
console.log('第二次请求')
console.log('第二次请求')
console.log('第二次请求')
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve()
}, 1000)
})
}).then(() => {
console.log('第三次请求')
console.log('第三次请求')
console.log('第三次请求')
console.log('第三次请求')
console.log('第三次请求')
})
链式调用
完整写法
const p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('这是')
},1000)
}).then(res => {
console.log(res)
return new Promise((resolve, reject) => {
resolve(res + '完整的')
})
}).then(res => {
console.log(res)
return new Promise((resolve, reject) => {
resolve(res + '一段话')
})
}).then(res => {
console.log(res)
})
简写
const p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('这是')
},1000)
}).then(res => {
console.log(res)
return Promise.resolve(res + '完整的')
}).then(res => {
console.log(res)
return Promise.resolve(res + '一段话')
}).then(res => {
console.log(res)
})
最简写
const p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('这是')
},1000)
}).then(res => {
console.log(res)
return res + '完整的'
}).then(res => {
console.log(res)
return res + '一段话'
}).then(res => {
console.log(res)
})
捕捉异常
在后面跟上.catch(error => console.log(error))