promise对象
Promise 是异步编程的一种解决方案。里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。
理解Promise
从语法上来说:Promise是一个构造函数
从功能上来说:Promise对象用来封装一个异步操作并获取其结果
状态的改变
pending
变为resolved
pending
变为rejected
只有这两种,且一个promise
对象只能改变一次
无论成功或失败,都只有一个结果
成功的数据一般称为value
,失败的结果一般称为reason
简单应用
// 创建一个promise对象
const p = new Promise((resolve, reject) => { // 执行器函数
// 执行异步任务
setTimeout(() => {
const time = Data.now()
if (time % 2 === 0) { // 成功则调用resolve()
resolve('成功的数据' + time)
} else { // 失败则调用reject()
reject('失败的数据' + time)
}
}, 2000)
})
// then方法接收两个回调函数,分别对应成功和失败
p.then(
value => {
console.log('成功的回调函数' + value)
},
reason => {
console.log('失败的回调函数' + reason)
}
)
解决文章开始的回调地狱
// 链式调用,代码优雅了许多,层次也更佳清晰
pSetTimeout('回')
.then(
value => {
console.log(value)
return pSetTimeout('调')
}
)
.then(
value => {
console.log(value)
return pSetTimeout('地')
}
)
.then(
value => {
console.log(value)
return pSetTimeout('狱')
}
).then(
value => {
console.log(value)
}
)
function pSetTimeout(str) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(str)
}, 2000)
})
}
如何使用Promise
静态方法
resolve(), reject()
返回一个以给定值解析后的Promise
对象,分别接收成功值和失败值
// 产生一个成功值为1的promise对象
const p1 = new Promise((resolve, reject) => resolve(1))
p1.then(value => console.log(value)) // 1
// 语法糖
// 产生一个成功值为2的promise对象
const p2 = Promise.resolve(2)
p2.then(value => console.log(value)) // 2
//产生一个失败值为3的promise对象
const p3 = Promise.reject(3)
p3.then((null, reason) => console.log(reason)) // 3
p3.catch(reason => console.log(reason)) // 3
all()
参数内所有的promise
对象都成功时回调成功(resolve
),若有一个失败则回调失败(reject
)。
成功的返回值是所有成功promise
的成功值组成的数组;失败的返回值是第一个失败promise
的结果
const p1 = Promise.resolve(1)
const p2 = Promise.resolve(2)
const p3 = Promise.reject(3)
const pAll1 = Promise.all([p1, p2, p3])
const pAll2 = Promise.all([p1, p2])
pAll1.then(
value => console.log('all onResolved()' + value),
reason => console.log('all onRejected()' + reason)
) // 3
pAll2.then(
value => console.log('all onResolved()' + value),
reason => console.log('all onRejected()' + reason)
) // [1, 2]
race()
使用方法与Promise.all()
相同
race
顾名思义 竞速,即当中的第一个promise
解决或失败,则返回这个promise
的值
实例方法
then()
then()
方法返回一个Promise
。它最多需要有两个参数:Promise
的成功和失败情况的回调函数。
catch()
catch()
方法返回一个Promise
,并且处理拒绝的情况。它的行为与调用Promise.prototype.then(undefined, onRejected)
相同。
finally()
finally()
方法返回一个Promise
。在promise
结束时,无论结果是fulfilled
或者是rejected
,都会执行指定的回调函数。这为在Promise
是否成功完成后都需要执行的代码提供了一种方式。这避免了同样的语句需要在then()
和catch()
中各写一次的情况。
自定义Promise
构造函数
function MyPromise(excutor) {
const self = this
self.status = 'pending'
self.data = undefined
self.callbacks = []
function resolve(value) {
if (self.status === 'pending') {
// 将状态改为resolved
self.status = 'resolved'
// 保存value数据
self.data = value
// 如果有待执行的callback函数,立即异步执行回调
if (self.callbacks.length > 0) {
setTimeout(() => { // 放入队列,执行所有成功的回调
self.callbacks.forEach(callbackObj => {
callbackObj.onResolved(value)
})
}, 0)
}
}
}
function reject(reason) {
if (self.status === 'pending') {
// 将状态改为rejected
self.status = 'rejected'
// 保存value数据
self.data = reason
// 如果有待执行的callback函数,立即异步执行回调
if (self.callbacks.length > 0) {
setTimeout(() => { // 放入队列,执行所有失败的回调
self.callbacks.forEach(callbackObj => {
callbackObj.onRejected(reason)
})
}, 0)
}
}
}
try {
excutor(resolve, reject)
} catch (error) {
reject(error)
}
}
then()方法
// then方法,指定成功和失败的回调函数,返回新的promise对象
MyPromise.prototype.then = function (onResolved, onRejected) {
onResolved = typeof onResolved === 'function' ? onResolved : value => value
// 指定默认的失败回调(实现错误/异常穿透的关键点)
onRejected = typeof onRejected === 'function' ? onRejected : reason => {
throw reason
}
const self = this
return new MyPromise((resolve, reject) => {
function handle(callback) {
// 1. 如果抛出异常,return的promise就会失败,reason就是error
// 2. 如果回调函数返回的不是promise,return的promise就会成功,value就是返回值
// 3. 如果返回的函数是promise,return的结果就是这个promise的结果
try {
const result = callback(self.data)
if (result instanceof MyPromise) {
// result.then(
// value => resolve(value),
// reason => reject(reason)
// )
result.then(resolve, reject)
} else {
resolve(result)
}
} catch (error) {
reject(error)
}
}
if (self.status === 'pending') {
self.callbacks.push({
onResolved() {
handle(onResolved)
},
onRejected() {
handle(onRejected)
}
})
} else if (self.status === 'resolved') {
setTimeout(() => {
handle(onResolved)
})
} else {
setTimeout(() => {
handle(onRejected)
})
}
})
}
catch()方法
// catch方法,指定失败的回调函数,返回新的promise对象
MyPromise.prototype.catch = function (onRejected) {
return this.then(undefined, onRejected)
}
resolve()方法
// 返回指定结果的成功的promise
MyPromise.resolve = function (value) {
return new MyPromise((resolve, reject) => {
// 返回一个成功/失败的promise
if (value instanceof MyPromise) { // value是promise 使用value的结果作为promise的结果
value.then(resolve, reject)
} else { // 若value不是promise,则成功 数据是value
resolve(value)
}
})
}
reject()方法
// 返回指定结果的失败的promise
MyPromise.reject = function (reason) {
// 返回一个失败的promise
return new MyPromise((resolve, reject) => {
reject(reason)
})
}
all()方法
// 返回一个promise,当所有promise都成功时才成功
MyPromise.all = function (promises) {
let resolveCount = 0;
const values = new Array(promises.length)
return new MyPromise((resolve, reject) => {
promises.forEach((p, index) => {
MyPromise.resolve(p).then(
value => {
resolveCount++
values[index] = value
if (resolveCount === promises.length) {
resolve(values)
}
},
reason => {
reject(reason)
}
)
})
})
}
race()方法
// 返回一个promise,由第一个有结果的promise决定
MyPromise.race = function (promises) {
return new MyPromise((resolve, reject) => {
promises.forEach((p, index) => {
MyPromise.resolve(p).then(
value => {
resolve(value)
},
reason => {
reject(reason)
}
)
})
})
}
合并成一个ES6语法的
class MyPromise {
constructor(excutor) {
const self = this
self.status = 'pending'
self.data = undefined
self.callbacks = []
function resolve(value) {
if (self.status === 'pending') {
// 将状态改为resolved
self.status = 'resolved'
// 保存value数据
self.data = value
// 如果有待执行的callback函数,立即异步执行回调
if (self.callbacks.length > 0) {
setTimeout(() => { // 放入队列,执行所有成功的回调
self.callbacks.forEach(callbackObj => {
callbackObj.onResolved(value)
})
}, 0)
}
}
}
function reject(reason) {
if (self.status === 'pending') {
// 将状态改为rejected
self.status = 'rejected'
// 保存value数据
self.data = reason
// 如果有待执行的callback函数,立即异步执行回调
if (self.callbacks.length > 0) {
setTimeout(() => { // 放入队列,执行所有失败的回调
self.callbacks.forEach(callbackObj => {
callbackObj.onRejected(reason)
})
}, 0)
}
}
}
try {
excutor(resolve, reject)
} catch (error) {
reject(error)
}
}
// then方法,指定成功和失败的回调函数,返回新的promise对象
then(onResolved, onRejected) {
const self = this
onResolved = typeof onResolved === 'function' ? onResolved : value => value
// 指定默认的失败回调(实现错误/异常穿透的关键点)
onRejected = typeof onRejected === 'function' ? onRejected : reason => {
throw reason
}
return new MyPromise((resolve, reject) => {
function handle(callback) {
// 1. 如果抛出异常,return的promise就会失败,reason就是error
// 2. 如果回调函数返回的不是promise,return的promise就会成功,value就是返回值
// 3. 如果返回的函数是promise,return的结果就是这个promise的结果
try {
const result = callback(self.data)
if (result instanceof MyPromise) {
// result.then(
// value => resolve(value),
// reason => reject(reason)
// )
result.then(resolve, reject)
} else {
resolve(result)
}
} catch (error) {
reject(error)
}
}
if (self.status === 'pending') {
self.callbacks.push({
onResolved() {
handle(onResolved)
},
onRejected() {
handle(onRejected)
}
})
} else if (self.status === 'resolved') {
setTimeout(() => {
handle(onResolved)
})
} else {
setTimeout(() => {
handle(onRejected)
})
}
})
}
// catch方法,指定失败的回调函数,返回新的promise对象
catch(onRejected) {
return this.then(undefined, onRejected)
}
// 返回指定结果的成功的promise
static resolve = function (value) {
return new MyPromise((resolve, reject) => {
// 返回一个成功/失败的promise
if (value instanceof MyPromise) { // value是promise 使用value的结果作为promise的结果
value.then(resolve, reject)
} else { // 若value不是promise,则成功 数据是value
resolve(value)
}
})
}
// 返回指定结果的失败的promise
static reject = function (reason) {
// 返回一个失败的promise
return new MyPromise((resolve, reject) => {
reject(reason)
})
}
// 返回一个promise,当所有promise都成功时才成功
static all = function (promises) {
let resolveCount = 0;
const values = new Array(promises.length)
return new MyPromise((resolve, reject) => {
promises.forEach((p, index) => {
MyPromise.resolve(p).then(
value => {
resolveCount++
values[index] = value
if (resolveCount === promises.length) {
resolve(values)
}
},
reason => {
reject(reason)
}
)
})
})
}
// 返回一个promise,由第一个有结果的promise决定
static race = function (promises) {
return new MyPromise((resolve, reject) => {
promises.forEach((p, index) => {
MyPromise.resolve(p).then(
value => {
resolve(value)
},
reason => {
reject(reason)
}
)
})
})
}
// 返回一个promise,他在指定时间后确定结果
static resolveDelay = function (value, time) {
return new MyPromise((resolve, reject) => {
setTimeout(() => {
// 返回一个成功/失败的promise
if (value instanceof MyPromise) { // value是promise 使用value的结果作为promise的结果
value.then(resolve, reject)
} else { // 若value不是promise,则成功 数据是value
resolve(value)
}
}, time)
})
}
// 返回一个promise,他在指定时间后失败
static rejectDelay = function (reason, time) {
// 返回一个失败的promise
return new MyPromise((resolve, reject) => {
setTimeout(() => {
reject(reason)
}, time)
})
}
}