Promise 介绍与基本使用
异步编程
- fs文件操作
require('fs').readFile('./index.html',(err,data)=>{})
- 数据库操作
- AJAX
$.get('/server',(data)=>{})
- 定时器
setTimeout(()=>{},1000)
为什么要用Promise
- 指定回调函数的方式更加灵活
- 支持链式调用,可以解决回调地狱问题
Promise 的状态
实例对象中的一个属性 [PromiseState]
- pending 未决定的
- resolved / fullfilled 成功
- rejected 失败
Promise 对象的值
实例对象中的另一个属性 [PromiseResult]
保存着对象[成功/失败]的结果
- resolve
- reject
Promise API
- Promise构造函数 Promise(excutor)
- Promise.prototype.then 方法:
(onResolved,onRejected)=>{}
- Promise.prototype.catch 失败后的回调
- Promise.resolve 方法:(value)=>{} 返回一个成功/失败的promise对象
- Promise.reject 方法:(reason)=>{} 返回一个失败的promise对象
- Promise.all 方法:(promise)=>{} 返回一个新的promise,只有所有的promise都成功才成功,只要有一个失败了就直接失败
let p1 = new Promise((resolve,reject)=>{ resolve('ok') }) //let p2 = Promise.resolve('Success') let p2 = Promise.reject('Error') let p3 = Promise.resolve('Oh Yeah') const result = Promise.all([p1,p2,p3]) console.log(result)
- Promise.race 方法:(promise)=>{} 返回一个新的promise,第一个完成的promise的结果状态就是最终的结果状态
let p1 = new Promise((resolve,reject)=>{ resolve('ok') }) let p2 = Promise.resolve('Success') let p3 = Promise.resolve('Oh Yeah') const result = Promise.race([p1,p2,p3]) console.log(result)
Promise 关键问题
- 如何修改对象的状态
let p = new Promise((resolve,reject)=>{
// 1. resolve函数
resolve('ok') // pending => fulfilled(resolved)
// 2. reject 函数
reject('error') // pending => rejected
// 3. 抛出错误
throw '出问题了'
})
console.log(p)
- 能够执行多个回调
let p = new Promise((resolve,reject)=>{
resolve('ok')
})
// 指定回调 - 1
p.then(value=>{
console.log(value)
})
// 指定回调 - 2
p.then(value=>{
alear(value)
})
- 改变promise状态和指定回调函数谁先谁后
都有可能,正常情况下是先指定回调再改变状态,但也可以先改状态再指定回调
let p = new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve('ok')
},1000)
})
p.then(value=>{
console.log(value)
},reason=>{
})
- promise.then()返回新的Promise的结果状态由什么决定?
由then()指定的回调函数执行的结果决定
let p = new Promise((resolve,reject)=>{
resolve('ok')
})
// 执行 then 方法
let result = p.then(value=>{
// console.log(value)
// 1. 抛出错误
// throw '出错了'
// 2. 返回结果是非 promise 类型的对象
return 521
// 3. 返回结果是 promise 对象
return new Promise((resolve,reject)=>{
// resolve('Success')
reject('Error')
})
},reason=>{
console.log(reason)
})
console.log(result)
- promise如何串连多个操作任务?
- promise的then()返回一个新的promise,可以开成then()的链式调用
- 调用then的链式调用串连多个同步/异步任务
let p = new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve('ok')
},1000)
})
p.then(value=>{
return new Promise((resolve,reject)=>{
resolve('success')
})
}).then(value=>{
console.log(value)
}).then(value=>{
console.log(value)
})
- promise 异常穿透
- 当使用promise的then链式调用时,可以在最后指定失败的回调
- 前面任何操作除了异常,都会传到最后失败的回调中处理
let p = new Promise((resolve,reject)=>{
// resolve('ok')
reject('Error')
})
p.then(value=>{
return new Promise((resolve,reject)=>{
resolve('success')
})
}).then(value=>{
console.log(111)
// throw '失败啦!' // 这里的错误会在最终的 catch方法去处理
// 中断promise链
return new Promise((resolve,reject)=>{})
}).then(value=>{
console.log(222)
}).then(value=>{
console.log(333)
}).catch(reason=>{
console.warn(reason)
})
- 终断promise链?
- 当时用promise的then链式调用时,在中间终端,不再调用后面的回调函数
- 办法:在回调函数中返回一个pending状态的promise对象