Promise简介
在ES6(ES2015)正式发布中,Promise 被列为正式规范,作为ES6中最重要的特性之一。
Promise 的出现主要是为了解决回调地狱问题,通过调用 .then 方法逐层去向下调用
Promise 对象有以下两个特点:
1、对象的状态不受外界影响。Promise 对象代表一个异步操作,有三种状态:
- pending: 初始状态,不是成功或失败状态。
- fulfilled: 意味着操作成功完成。
- rejected: 意味着操作失败。
2、一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise 对象的状态改变,只有两种可能:从 Pending 变为 Resolved 和从 Pending 变为 Rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果。
Promise的用法
Promise 的构造函数接收一个参数,是函数,并且传入两个参数:resolve,reject,分别表示异步操作执行成功后的回调函数和异步操作执行失败后的回调函数。其实这里用 “成功” 和 “失败” 来描述并不准确,按照标准来讲,resolve 是将 Promise 的状态置为 fullfiled,reject 是将 Promise 的状态置为 rejected 。
let promi = new Promise((resolve, reject) => {
resolve('new promise111111')
// reject('error')
})
/*
在promise中我们可以手动去调用resolve, reject去执行成功/失败的状态
!!!!!!promise中的状态由pedding变更为其他状态后就不可再次更改了
*/
promi.then(res => {
// 这里拿到的就是resolve中传入的参数
console.log(res);
}, reason => {
// 这里拿到的就是reject中传入的参数
console.log(reason);
})
实现一个原生简易版本的 Promise
我们可以根据 Promise 的使用方式来逆解析它内部的处理逻辑
- 它接收一个匿名函数来作为参数
- 使用 resolve 方法返回成功状态
- 使用 reject 方法返回失败状态
- 调用 then 方法去处理成功/失败的状态
具体实现
- 通过 class 关键字创建一个类出来
- 在类中使用 constructor 方法接收外部传入过来的匿名函数
- promise 的状态一经变更就不在更改
- 执行这个匿名函数, 并传入 resolve, reject 方法
- then 方法的处理
- 处理异步情况
基本实现
// 保存Promise的三个状态, 以便后续调用
const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
class iPromise {
constructor(callback) {
// 接收执行外部传入的匿名函数
callback(this.resolve, this.reject)
}
value = null // --> 成功的值
status = PENDING // --> promise声明时默认为pending(执行中)的状态
reason = null // --> 失败的原因
resolve = (value) => {
// 判断当前promise的状态是否已经变更过, 如果变更过就不做任何操作
if (this.status !== PENDING) {
return
}
// 变更promise的状态, 并获取promise的成功参数保存到promise内, 在成功的回调中暴露出去
this.status = FULFILLED
this.value = value
}
reject = (reason) => {
// 判断当前promise的状态是否已经变更过, 如果变更过就不做任何操作
if (this.status !== PENDING) {
return
}
// 变更promise的状态, 并获取promise的失败参数, 在失败的回调中暴露出去
this.status = REJECTED
this.reason = reason
}
then(successCallback, errorCallback) {
if (this.status == FULFILLED) {
successCallback(this.value)
} else if (this.status == REJECTED) {
errorCallback(this.reason)
}
}
}
写到这一步这样可以基本实现简易版本 Promise 第一步了
let promise = new iPromise((resolve, reject) => {
resolve('new promise')
// reject('reaspn')
})
promise.then(res => {
console.log(res);// new Promises
}, reason => {
console.log(reason);
})
处理 promise 的异步情况
处理异步调用的情况,就需要我们在 then 方法执行的时候,将成功 / 失败的回调函数保存起来,当异步任务结束触发 resolve、reject 的时候去再去执行成功/失败的回调函数
class iPromise {
FILFULLD // --> 成功的回调函数
REJECTED // --> 失败的回调函数
resolve = (value) => {
if (this.status != PENDING) {
return
}
this.status = FULFILLED
this.value = value
// 如果有这个函数就执行它, 并传入成功的值
this.FILFULLD && this.FILFULLD(this.value)
}
reject = (reason) => {
if (this.status != PENDING) {
return
}
this.status = REJECTED
this.reason = reason
// 如果有这个函数就执行它, 并传入失败的原因
this.REJECTED && this.REJECTED(this.reason)
}
// 判断当前执行状态是成功还是失败, 并调用对应的回调函数
then(successCallback, errorCallback) {
// 将成功/失败的回调函数保存到promise的原型上
this.FILFULLD = successCallback
this.REJECTED = errorCallback
if (this.status == FULFILLED) {
successCallback(this.value)
} else if (this.status == REJECTED) {
errorCallback(this.reason)
}
}
}
简易的完整版本
// 保存Promise的三个状态, 以便后续调用
const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
class iPromise {
constructor(callback) {
// 接收执行外部传入的匿名函数
callback(this.resolve, this.reject)
}
value = null // --> 成功的值
status = PENDING // --> promise声明时默认为pending(执行中)的状态
reason = null // --> 失败的原因
FILFULLD
REJECTED
resolve = (value) => {
if (this.status != PENDING) {
return
}
this.status = FULFILLED
this.value = value
this.FILFULLD && this.FILFULLD(this.value)
}
reject = (reason) => {
if (this.status != PENDING) {
return
}
this.status = REJECTED
this.reason = reason
this.REJECTED && this.REJECTED(this.reason)
}
// 判断当前执行状态是成功还是失败, 并调用对应的回调函数
then(successCallback, errorCallback) {
this.FILFULLD = successCallback
this.REJECTED = errorCallback
if (this.status == FULFILLED) {
successCallback(this.value)
} else if (this.status == REJECTED) {
errorCallback(this.reason)
}
}
}
处理异步情况之后的用法
这里使用 setTimeout 来模拟了一下异步的情况
let promise = new iPromise((resolve, reject) => {
setTimeout(() => {
resolve('new promise')
}, 1000)
// reject('reaspn')
})
promise.then(res => {
console.log(res); // new promise
}, reason => {
console.log(reason);
})
到这里本章节的简易版本的 Promise 就基本可以实现了, 当然这也只是一部分, 后面将逐步剖析 Promise 的后续操作
- 处理 Promise.then 方法链式调用识别 Promise 对象
- 处理函数执行的异常情况
- 实现 Promise.all 的静态方法
- 实现 Promise.finally 的静态方法
- 实现 Promise.resolve 的静态方法
- 实现 Promise.catch 的静态方法