源码very-simple-promise,包含了不完善的单元测试❤️.感谢代码君的自白这篇的文章主要参考了上面的博客,谢谢他的帮助????。Promise/A+规范Promises/A+规范, 下面????是对规范的内容的部分翻译。英文比较烂,不喜欢的可以不看。承诺必须满足三种状态, pending(等处理), fulfilled(履行), rejected(拒绝)Promises的状态promise处于pending时可以过渡到fulfilled或者rejected状态promise处于fulfilled时不能向其他状态过渡promise处于rejected时不能向其他状态过渡thenpromise的then方法接受两个参数promise.then(onFulfilled, onRejected)onFulfilled和onRejected都是可选参数onFulfilled不是函数需要忽略onRejected不是函数需要忽略onFulfilled如果是一个函数onFulfilled在promise状态为fulfilled时被调用onFulfilled只能被调用一次onFulfilled不能在fulfilled之前不能调用onRejected如果是一个函数onRejected在promise状态为rejected时被调用在rejected之前不能调用它onRejected只能被调用一次onFulfilled or onRejected must not be called until the execution context stack contains only platform code. (原文不太懂什么意思,但是规范给出了注解)onFulfilled和onRejected必须作为函数调用then可以在同一个promise多次调用如果promise被履行, 则onFulfilled回调必须按照then的顺序执行如果promise被拒绝, 则onRejected回调必须按照then的顺序执行promise2 = promise1.then(onFulfilled, onRejected);then必须返回promise如果onFulfilled或者onRejected返回一个值,则运行处理Promise的过程[[Resolve]](promise2, x)(这里处理的Resolve(promise2, x), onFulfilled或者onRejected的返回值会被resolve处理, resolve的第一个参数是then返回的新的promise)如果onFulfilled, onRejected抛出错误error, 则promise2必须为rejected如果onFulfilled不是一个函数, 而promise1的状态为fulfilled, promise2必须与promise1具有相同的值被履行如果onRejected不是一个函数, 而promise1的状态为rejected, promise2必须与promise1具有相同的值被拒绝处理Promise[[Resolve]](promise, x)需要遵循以下规范如果promise与x相等, 抛出TypeError的错误, 并以错误为理由拒绝promise如果x是Promise如果x处于pending,promise也需要保持pending,直到x接受pending如果x处于fulfilled,promise需要使用相同值执行promise如果x处于rejected,promise需要使用相同的值拒绝promise如果x是对象或者函数将x.then赋于then如果获取x.then时抛出错误,则使用错误作为理由拒绝promise如果then是函数????️使用x作为then函数的作用域中的this, 传入两个参数作为回调,分别是resolvePromise, 和rejectPromise如果resolvePromise如果以y为参数运行,则运行[[Resolve]](promise, y), 履行promise。resolve(promise,y)如果rejectPromise以r为参数运行,则以r为原因拒绝promise。reject(promise, r)如果then抛出了错误如果resolvePromise,rejectPromise已经调用对错误忽略如果没有调用,用错误作为原因拒绝promise如果then不是函数,使用x作为参数执行promise如果x不是对象也不是函数,则使用x作为参数执行promise注解onFulfilled和onRejected方法应当是异步执行,且应该在then方法被调用的那一轮事件循环之后的微任务执行栈中执行。可以使用宏任务macrotask和微任务microtask机制实现。也就是说宏任务完成后(Promise的then调用后),会清空微任务队列(执行onFulfilled或者onRejected)。macrotask包含:script(整体代码)、setTimeout、setInterval、I/O、UI交互事件、postMessage 、requestAnimationFrame 、MessageChannel、etImmediate(Node.js 环境)microtask包含:Promise.then、setImmediate、MutaionObserver、process.nextTick(Node.js 环境)事件循环下面????是一个关于事件循环的例子????Promise中的参数函数,应当是立即调用的。我们这时先执行了resolve(1), 这会将外层的Promise的状态置为fulfilled态。但是这时外层的then还没有执行。我们接下来执行了Promise.resolve().then(() => console.log(2)), 我们将then的onFulfilled,push到了macrotask队列中,会在宏任务执行完成后清空微任务。执行外层Promise的then, onFulfilled, push到了macrotask队列中。接着执行console.log(3), 然后清空macrotask队列,执行2,1(队列先进先出)Promise构造函数const pending = 0const fulfilled = 1const rejected = 2function reject (promise, result) {}function resolve (promise, reason) {}export default class Promise { constructor (fn) { this.fn = fn // Promise的状态, 初始状态为pending this._state = pending // Promise的fulfilled态的原因,或者Promise的rejected态的理由 this._value = null // 存储then的队列 this._tasks = [] // 创建Promise对象后,立即执行fn this.init() } init () { try { // 执行fn, 传入包装后的resolve,reject // reject,resolve会修改promise的状态 this.fn( (result) => resolve(this, result), (reason) => reject(this, reason) ) } catch (error) { reject(this) } }}根据规范2.2.6: then may be called multiple times on the same promisethen可以在同一个promise中多次调用。所以我们用一个数组存储then的结果。Promise.prototype.then根据规范2.2.1: A promise’s then method accepts two arguments. Both onFulfilled and onRejected are optional arguments。then接受两个参数, 两个参数可选。根据规范2.2.1.1, 2.2.1.2: If onFulfilled is not a function, it must be ignored. If onRejected is not a function, it must be ignored.。onFulfilled, onRejected必须是函数负责会被忽略。根据规范2.2.2, 2.2.3, onFulfilled必须在状态为fulfilled调用, onRejected必须在状态为rejected调用根据规范2.2.7: then must return a promise。then必须返回一个promise。????️ 为什么不能返回当前的promise?因为根据规范2.1.2, 2.1.3, promise被修改状态后,不能再次修改状态。我们如果需要执行then的callback需要修改promise的状态。我们使用task封装????then的回调以及then返回的promise。class Task { constructor (onFulfilled, onRejected, promise) { if (typeof onFulfilled !== ‘function’) { onFulfilled = null } if (typeof onRejected !== ‘function’) { onRejected = null } this.onFulfilled = onFulfilled this.onRejected = onRejected this.promise = promise }}class Promise { // … then (onFulfilled, onRejected) { let nextPromise = new Promise(function () {}) let task = new Task(onFulfilled, onRejected, nextPromise) if (this._state === pending) { this._tasks.push(task) } else { handlePromise(this, task) } // 返回新的promise return nextPromise }}Promise.prototype.catchcatch函数同样会返回新的promise, 但是在创建task时,我们不会传入onFulfilled参数。所以当promise当为fulfilled态,虽然catch的回调同样存放_task中,但是由于callback为null, 在handlePromise中会向下穿透。class Promise { // … catch (onRejected) { let nextPromise = new Promise(function () {}) // onFulfilled设置为null let task = new Task(null, onRejected, nextPromise) if (this.state === pending) { this.tasks.push(task) } else { handlePromise(this, task) } // 返回新的promise return nextPromise }}Promise.prototype.finallyfinally方法用于指定不管Promise对象最后状态如何,都会执行的操作。我们无论promise的状态如何,都在promise的最后面添加then,并传入了onFulfilled, onRejected两个回调。在回调中,我们执行finally的callback参数。这样无论之前的promise是fulfilled态,还是rejected态,都会执行finally添加的参数。class Promise { // … finally (callback) { // this指向调用finally的对象 const self = this // 向Promise链中添加then,无论,promise是resolve态还是reject态,都会执行callback // 并且会通过then,继续将result或reason向下传递 return self.then( result => Promise.resolve(callback()).then( => result), reason => Promise.resolve(callback()).then( => { throw reason }) ) }}resolveresolve用来修改promise状态,将promise状态设置为fulfilled态, 并执行then的onFulfilled回调根据规范2.3.1: If promise and x refer to the same object, reject promise with a TypeError as the reason.如果promise与x相等,我们使用TypeError的错误拒绝promise根据规范2.3.2。如果result是promise,并且处于pending态,promise需要保持pending态,直到result被执行和拒绝后,我们使用result的状态履行或者拒绝promise。如果result是promise,并且处于fulfilled或rejected态,我们使用result的状态拒绝或者履行promise。根据规范2.3.3, 我们判断result是否为一个Object。如果result为Object, 我们则取出它的then的属性, 判断then属性是否为Function, 如果then为Function, 我们设置then的作用域的this指向result, 我们传入resolvePromise, rejectPromise作为参数。根据规范2.3.4: If x is not an object or function, fulfill promise with x, 如果x不是函数或者对象,我们用result结果作为参数执行promise。function resolve (promise, result) { if (promise === result) { throw reject(promise, new TypeError(‘promise and x refer to the same object’)) } if (isPromise(result)) { if (result._state === pending) { result._tasks.concat(promise._tasks) } else if (result._state === fulfilled || result._state === rejected) { let task while (task = promise._tasks.shift()) { handlePromise(result, task) } } return } if (isObject(result)) { let then = null try { then = result.then } catch (error) { reject(promise, error) } if (isFunction(then)) { try { let resolvePromise = function (y) { resolve(promise, y) } let rejectPromise = function (r) { reject(promise, r) } then.call(result, resolvePromise, rejectPromise) } catch (error) { reject(promise, error) } return } } promise._state = fulfilled promise._value = result if (promise._tasks && promise._tasks.length) { let task = null while (task = promise._tasks.shift()) { handlePromise(promise, task) } }}rejectreject将promise的状态设置为rejected, 并以当前的promise的状态,执行promise中通过then注册的onRejected回调。function reject (promise, reason) { if (promise._state !== pending) { return } promise._state = rejected promise._value = reason let task while (task = promise._tasks.shift()) { handlePromise(promise, task) }}handlePromisehandlePromise函数主要根据当前的promise的状态, 以及内容(resolve或者reject的参数)。处理通过then注册的回调。并且会链式的调用,注册在then返回的新promise的上的then的回调// 将回调的结果,传入第二个then中fn().then().then()根据规范2.2.4, 以及规范给出的注解。当promise的状态改变,onFulfilled, onRejected并不会立即执行,而且在本次的宏任务完成后,才会执行onFulfilled或者onRejected。而setImmediate则是将代码push到微任务队列中。在宏任务中会清空微任务队列。function handlePromise (prevPromise, task) { // 需要在宏任务完后的微任务队列中执行 setImmediate(() => { // nextPromise是then返回的promise const { onFulfilled, onRejected, promise: nextPromise } = task let callback = null let value = prevPromise._value let state = prevPromise.state if (state === fulfilled) { callback = onFulfilled } else if (state === rejected) { callback = onRejected } if (!callback) { // 如果在promise中没有注册callback if (state === fulfilled) { resolve(nextPromise, value) } else if (state === rejected) { reject(nextPromise, value) } } else { try { const result = callback(value) // 对then中返回promise处理 // 将callback返回的结果,带入到新的promise中 resolve(nextPromise, result) } catch (error) { reject(nextPromise, error) } } })}Promise.resolve & Promise.rejectPromise.resolve方法返回一个新的Promise对象,状态为resolved。Promise.reject(reason)方法也会返回一个新的 Promise实例,该实例的状态为rejected。class Promise { // … static resolve (result) { return new Promise((resolve) => { resolve(result) }) } static reject (reason) { return new Promise((, reject) => { reject(reason) }) }}Promise.all && Promise.racePromise.all和Promise.race必须接受一个数组为参数,数组中为多个Promise的实例。Promise.all和Promise.race的使用我就不再这里赘述了。Promise.all会使用计数器,记录Promise数组中的所有Promise实例的状态是否都变为fulfilled态,如果计数器的长度和数组长度一致,我们则会将Promise.all的状态设置为fulfilled态。class Promise { static race (promises) { if (isArray(promises)) { let promisesLength = promises.length return new Promise((resolve, reject) => { for (let i = 0; i < promisesLength; i++) { promises[i].then((result) => { resolve(result) }).catch((error) => { reject(error) }) } }) } else { throw new TypeError(‘The arguments must be arrays’) } } static all (promises) { if (isArray(promises)) { let promisesLength = promises.length let counter = 0 let resultList = [] return new Promise((resolve, reject) => { for (let i = 0; i < promisesLength; i++) { promises[i].then((result) => { counter += 1 resultList.push(result) if (counter === promisesLength) { resolve(resultList) } }).catch((error) => { reject(error) }) } }) } else { throw new TypeError(‘The arguments must be arrays’) } }}其他VueRouter源码分析Preact源码分析