haohaio
努力学习,艰苦奋斗
写写代码,记记笔记
Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了 Promise 对象。
基本结构
话不多说,我们先实现 Promise 的基本结构,我们需要注意以下几点:
- 构造函数 Promise 接受一个函数作为参数,该函数包含 resolve 和 reject 两个参数,它们是两个函数。
- Promise 对象有三种状态:Pending(进行中)、Fulfilled(已成功)、Rejected(已失败)。状态只能由 Pending 变为 Fulfilled 或由 Pending 变为 Rejected ,且状态改变之后不会在发生变化,会一直保持这个状态。
- resolve 方法将 Promise 对象的状态从 Pending 变为 Fulfilled。
- reject 方法将 Promise 对象的状态从 Pending 变为 Rejected。
- resolve 和 reject 都可以传入任意类型的值作为实参,表示 Promise 对象成功(Fulfilled)和失败(Rejected)的值
基于以上几点,我们实现代码如下:
const PENDING = Symbol('pending') const FULFILLED = Symbol('fulfilled') const REJECTED = Symbol('rejected')
const resolvePromise = (promise2, x, resolve, reject) => { if (promise2 === x) { return reject(new TypeError('cycle error')) }
if ((typeof x === 'object' && x !== null) || typeof x === 'function') { let called = false try { let then = x.then if (typeof then === 'function') { then.call( x, (y) => { if (called) { return } called = true resolvePromise(promise2, y, resolve, reject) }, (e) => { if (called) { return } called = true reject(e) } ) } else { resolve(x) } } catch (error) { if (called) { return } called = true reject(error) } } else { resolve(x) } }
class Promise { constructor(executor) { this.status = PENDING this.value = undefined this.reason = undefined this.onFulfilledCallbacks = [] this.onRejectedCallbacks = [] const resolve = (value) => { if (this.status === PENDING) { this.value = value this.status = FULFILLED this.onFulfilledCallbacks.forEach((fn) => fn()) } }
const reject = (reason) => { if (this.status === PENDING) { this.reason = reason this.status = REJECTED this.onRejectedCallbacks.forEach((fn) => fn()) } }
try { executor(resolve, reject) } catch (error) { reject(error) } }
then(onFulfilled, onRejected) { onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : (val) => val onRejected = typeof onRejected === 'function' ? onRejected : (err) => { throw err }
const promise2 = new Promise((resolve, reject) => { const fulfilled = () => { setTimeout(() => { try { let x = onFulfilled(this.value) resolvePromise(promise2, x, resolve, reject) } catch (error) { reject(error) } }, 0) }
const rejected = () => { setTimeout(() => { try { let x = onRejected(this.reason) resolvePromise(promise2, x, resolve, reject) } catch (error) { reject(error) } }, 0) }
switch (this.status) { case FULFILLED: fulfilled() break case REJECTED: rejected() break case PENDING: this.onFulfilledCallbacks.push(fulfilled) this.onRejectedCallbacks.push(rejected) break
default: break } })
return promise2 } }
Promise.defer = Promise.deferred = function () { const defer = {} defer.promise = new Promise((resolve, reject) => { defer.resolve = resolve defer.reject = reject })
return defer }
module.exports = Promise
|
这样,Promise 的基本功能算是实现了~~
最后我们可以用 promises-aplus-tests 库,来验证下我们写的 promise 是否符合 Promises/A+ 规范。
npm i promises-aplus-tests -g promises-aplus-tests promise.js
|
本文代表个人观点,内容仅供参考。若有不恰当之处,望不吝赐教!