Promise 是异步编程的一种解决方案,其实是一个构造函数,自己身上有all、reject、resolve这几个方法,原型上有then、catch等方法。
Promise对象有以下两个特点。
(1)对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是Promise这个名字的由来,它的英语意思就是“承诺”,表示其他手段无法改变。
(2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)。如果改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。
内部调用then
处理异常
- <script>
- // 定义函数
- function runAsynctask(callback) {// callback 是一个回调函数
- // 调用核心api
- if (typeof queueMicrotask === 'function') { // 调用三个函数是为了解决浏览器不兼容问题,先判断是不是函数
- queueMicrotask(callback)
- } else if (typeof MutationObserver === "function") {
- const obs = new MutationObserver(callback)
- const divNode = document.createElement('div')
- obs.observe(divNode, { childList: true })
- divNode.innerHTML = '打酱油改变以下内容'
- } else {
- setTimeout(callback, 0)
- }
- }
-
- const PENDING = 'pending'
- const FULFILLED = 'fulfilled'
- const REJECTED = 'rejected'
- class wePromise {
- state = PENDING // 状态
- result = undefined // 原因
- #handlers = [] // [{onFulfilled,onReject},......]
- // 构造函数
- constructor(func) {
- // 改状态,pending => fulfilled
- const reslove = (result) => {
- if (this.state === PENDING) {
- this.state = FULFILLED
- this.result = result
- // 下面这个是异步的时候,先保存,然后到这一步执行,就取出保存的函数并且执行
- this.#handlers.forEach(({ onFulfilled }) => { // 解构
- onFulfilled(this.result)
- })
- }
- }
- // 改状态,pending => rejected
- const reject = (result) => {
- if (this.state === PENDING) {
- this.state = REJECTED
- this.result = result
- this.#handlers.forEach(({ onReject }) => {
- onReject(this.result)
- })
- }
- }
-
- // 异常的处理
- try {
- // 执行回调函数
- func(reslove, reject)
- } catch (error) {
- reject(error)
- }
- }
-
- then(onFulfilled, onReject) {
- // 判断传入的参数是不是函数
- onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : x => x
- onReject = typeof onReject === 'function' ? onReject : x => { throw x }
-
- const p2 = new wePromise((reslove, reject) => {
- // 判断执行完成后的状态
- if (this.state === FULFILLED) {
- runAsynctask(() => {
- try {
- // 获取返回值
- const x = onFulfilled(this.result) // 返回结果
- reslovePromise(p2, x, reslove, reject)
- } catch (error) {
- // 处理异常
- reject(error)
- }
-
- })
- } else if (this.state === REJECTED) {
- runAsynctask(() => {
- try {
- const x = onReject(this.result)
- reslovePromise(p2, x, reslove, reject)
- } catch (error) {
- reject(error)
- }
- })
- } else if (this.state === PENDING) { // 还没有改变状态,说明是异步
- // 保存回调函数
- this.#handlers.push({
- onFulfilled: () => {
- runAsynctask(() => {
- try {
- const x = onFulfilled(this.result) // 返回结果
- reslovePromise(p2, x, reslove, reject)
- } catch (error) {
- reject(error)
- }
- })
- },
- onReject: () => {
- runAsynctask(() => {
- try {
- const x = onReject(this.result) // 返回结果
- reslovePromise(p2, x, reslove, reject)
- } catch (error) {
- reject(error)
- }
- })
- }
- })
- }
- })
-
-
- return p2
- }
- catch(onReject) {
- // 内部调用then方法
- return this.then(undefined, onReject)
- }
- finally(onFinally){
- return this.then(onFinally,onFinally)
- }
- }
-
- function reslovePromise(p2, x, reslove, reject) {
- // 处理重复引用
- if (x === p2) {
- // 抛出错误
- throw new TypeError('Chaining cycle detected for promise #
' ) - }
- // 处理返回的Promise
- if (x instanceof wePromise) {
- // 调用then方法
- x.then(res => reslove(res), err => reject(err))
- } else {
- // 处理返回值
- reslove(x)
- }
- }
- // 创建对象,调用两个方法
- const p = new wePromise((reslove, reject) => {
- // reslove('success')
- // reject('reject')
- throw 'throw-error'
- })
- p.then(res => {
- console.log('成功回调1:', res);
- // throw 'throw-error'
- // return 2
- }).catch(err => {
- console.log('失败回调1:', err);
-
- }).finally(() => {
- console.log('finally');
- })
- script>
- body>

- <script>
- // 定义函数
- function runAsynctask(callback) {// callback 是一个回调函数
- // 调用核心api
- if (typeof queueMicrotask === 'function') { // 调用三个函数是为了解决浏览器不兼容问题,先判断是不是函数
- queueMicrotask(callback)
- } else if (typeof MutationObserver === "function") {
- const obs = new MutationObserver(callback)
- const divNode = document.createElement('div')
- obs.observe(divNode, { childList: true })
- divNode.innerHTML = '打酱油改变以下内容'
- } else {
- setTimeout(callback, 0)
- }
- }
-
- const PENDING = 'pending'
- const FULFILLED = 'fulfilled'
- const REJECTED = 'rejected'
- class wePromise {
- state = PENDING // 状态
- result = undefined // 原因
- #handlers = [] // [{onFulfilled,onReject},......]
- // 构造函数
- constructor(func) {
- // 改状态,pending => fulfilled
- const reslove = (result) => {
- if (this.state === PENDING) {
- this.state = FULFILLED
- this.result = result
- // 下面这个是异步的时候,先保存,然后到这一步执行,就取出保存的函数并且执行
- this.#handlers.forEach(({ onFulfilled }) => { // 解构
- onFulfilled(this.result)
- })
- }
- }
- // 改状态,pending => rejected
- const reject = (result) => {
- if (this.state === PENDING) {
- this.state = REJECTED
- this.result = result
- this.#handlers.forEach(({ onReject }) => {
- onReject(this.result)
- })
- }
- }
-
- // 异常的处理
- try {
- // 执行回调函数
- func(reslove, reject)
- } catch (error) {
- reject(error)
- }
- }
-
- then(onFulfilled, onReject) {
- // 判断传入的参数是不是函数
- onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : x => x
- onReject = typeof onReject === 'function' ? onReject : x => { throw x }
-
- const p2 = new wePromise((reslove, reject) => {
- // 判断执行完成后的状态
- if (this.state === FULFILLED) {
- runAsynctask(() => {
- try {
- // 获取返回值
- const x = onFulfilled(this.result) // 返回结果
- reslovePromise(p2, x, reslove, reject)
- } catch (error) {
- // 处理异常
- reject(error)
- }
-
- })
- } else if (this.state === REJECTED) {
- runAsynctask(() => {
- try {
- const x = onReject(this.result)
- reslovePromise(p2, x, reslove, reject)
- } catch (error) {
- reject(error)
- }
- })
- } else if (this.state === PENDING) { // 还没有改变状态,说明是异步
- // 保存回调函数
- this.#handlers.push({
- onFulfilled: () => {
- runAsynctask(() => {
- try {
- const x = onFulfilled(this.result) // 返回结果
- reslovePromise(p2, x, reslove, reject)
- } catch (error) {
- reject(error)
- }
- })
- },
- onReject: () => {
- runAsynctask(() => {
- try {
- const x = onReject(this.result) // 返回结果
- reslovePromise(p2, x, reslove, reject)
- } catch (error) {
- reject(error)
- }
- })
- }
- })
- }
- })
-
-
- return p2
- }
-
- // 实例方法
- catch(onReject) {
- // 内部调用then方法
- return this.then(undefined, onReject)
- }
- finally(onFinally) {
- return this.then(onFinally, onFinally)
- }
-
- // 静态方法
- static reslove(value) {
- // 判断传入的是不是Promise对象
- if (value instanceof wePromise) {
- return value
- }
- return new wePromise((reslove, reject) => {
- reslove(value)
- })
-
- }
- static reject(value) {
- return new wePromise((reslove, reject) => {
- reject(value)
- })
- }
- static race(promises) {
- return new wePromise((reslove, reject) => {
- // 判断是否为数组
- if (!Array.isArray(promises)) {
- return reject(new TypeError('Argument is not iterable'))
- }
- // 等待第一个敲定
- promises.forEach(p => {
- wePromise.reslove(p).then(res => { reslove(res) }, err => { reject(err) })
- })
- })
- }
- // 重要
- static all(promises) {
- // 返回Promise实例
- return new wePromise((reslove, reject) => {
- // 判断是否为数组
- if (!Array.isArray(promises)) {
- return reject(new TypeError('Argument is not iterable'))
- }
- // 空数组直接兑换
- promises.length === 0 && reslove(promises)
- // 处理全部兑现
- const results = []
- let count = 0
- promises.forEach((p, index) => {
- wePromise.reslove(p).then(res => {
- results[index] = res
- count++
- // 判断全部兑现
- count === promises.length && reslove(results)
- }, err => {
- // 处理第一个拒绝
- reject(err)
- })
- })
- })
- }
- static allSettled(promises) {
- // 返回Promise实例
- return new wePromise((reslove, reject) => {
- // 判断是否为数组
- if (!Array.isArray(promises)) {
- return reject(new TypeError('Argument is not iterable'))
- }
- // 空数组直接兑换
- promises.length === 0 && reslove(promises)
- // 等待全部敲定
- const results = []
- let count = 0
- promises.forEach(p => {
- // 之所以是使用这个静态方法,是因为这个将传入的对象包装成了wePromise
- wePromise.reslove(p).then((res => {
- // 处理兑现
- results[index] = { status: FULFILLED, value: res }
- count++
- count === promises.length && reslove(results)
- }, err => {
- results[index] = { status: REJECTED, reason: err }
- count++
- count === promises.length && reslove(results)
- }))
- })
-
- })
- }
- static any(promises) {
- return new wePromise((reslove, reject) => {
- // 判断是否为数组
- if (!Array.isArray(promises)) {
- return reject(new TypeError('Argument is not iterable'))
- }
- // 空数组直接拒绝
- promises.length === 0 && reject(new AggregateError(promises, 'All promises were rejected'))
-
- // 等待结果
- const errors = []
- let count = 0
- promises.forEach((p, index) => {
- wePromise.reslove(p).then(res => {
- // 第一个兑现
- reslove(res)
- }, err => {
- // 全部拒绝
- errors === promises.length && reject(new AggregateError(errors, 'All promises were rejected'))
- })
- })
-
-
- })
- }
-
- }
-
- function reslovePromise(p2, x, reslove, reject) {
- // 处理重复引用
- if (x === p2) {
- // 抛出错误
- throw new TypeError('Chaining cycle detected for promise #
' ) - }
- // 处理返回的Promise
- if (x instanceof wePromise) {
- // 调用then方法
- x.then(res => reslove(res), err => reject(err))
- } else {
- // 处理返回值
- reslove(x)
- }
- }
- // 创建对象,调用两个方法
- const p = new wePromise((reslove, reject) => {
- // reslove('success')
- // reject('reject')
- throw 'throw-error'
- })
- p.then(res => {
- console.log('成功回调1:', res);
- // throw 'throw-error'
- // return 2
- }).catch(err => {
- console.log('失败回调1:', err);
-
- }).finally(() => {
- console.log('finally');
- })
- script>
- body>

这里运行效果请复制代码自己测,实例方法和静态方法已经是全部实现了的。
Promise 是异步编程的一种解决方案,其在工作的项目开发中是非常常用的,熟练的掌握Promise 的内容,熟悉底层源码,可以让我们在项目开发中具备更高超的代码书写能力,同时降低自己在使用Promise 出现的各种bug。好啦,Promise 源码系列到此就算是结束啦,希望能够对各位小伙伴有所帮助哦!